【问题标题】:Rename field after aggregate MongoDB聚合 MongoDB 后重命名字段
【发布时间】:2018-08-06 19:29:19
【问题描述】:

在 MongoDB 中执行以下查询

roles.aggregate([
      {'$unwind': '$skills'},
      {'$lookup': {
          'from': 'skills',
          'localField': 'skills._id',
          'foreignField': '_id',
          'as': 'skillsInfo'
      }},
      {'$unwind': '$skillsInfo'},
      {'$addFields': {'skills': {'$mergeObjects': ['$skills', '$skillsInfo']}}},
      {'$project': {'skillsInfo': 0}},
      {'$group': {
          '_id': '$_id',
          'name': {'$first': '$name'},
          'description': {'$first': '$description'},
          'departments': {'$first': '$departments'},
          'skills': {'$push': '$skills'},
          'deep' : {'$first' : '$deep'},
          'range': {'$first' : '$range'},
          'employees': {'$first' : '$employees'}
      }},
      {'$lookup': {
          'from': 'departments',
          'localField': 'departments',
          'foreignField': '_id',
          'as': 'departments'
      }}
  ])

我有这样的结果:

{
  "code": 10, 
  "deep": 1, 
  "departments": [
    {
      "_id": 0, 
      ....
    }
  ], 
  "description": "ER expert", 
  "employees": [
    1, 
    0
  ], 
  "name": "Database Designer", 
  "range": {
    "int": 75, 
    "min": 40
  }, 
  "skills": [
    {
      "_id": 2, 
      ....
    }
  ]
}

有没有办法在“code”中替换子文档键“_id”的名称?例如,我希望“departments._id”为“departments.code”。技能也是一样。无论如何,如果重要的话,我正在使用 MongoDB 3.6 和 PyMongo。 谢谢

【问题讨论】:

  • 您使用的是哪个 MongoDB 版本?

标签: mongodb


【解决方案1】:

从 v3.6 开始,$lookup 阶段支持special syntax for "nested queries"。尝试用以下版本替换最后的 $lookup 阶段:

$lookup: {
    from: "departments",
    let: { "departments": "$departments" },
    pipeline: [{
        $match: {
            $expr: {
                $in: [ "$_id",  "$$departments" ] // this just does the "join"
            }
        }
    }, {
        $addFields: {
            "code": "$_id" // create a field named "code" that contains the "_id" field's value
        }
    }, {
        $project: {
            _id: 0 // remove _id field
        }
    }],
    as: "departments"
}

【讨论】:

    【解决方案2】:

    您也可以使用$map。通过向您已有的结果添加新阶段:

    {
        $project: {
            code: 1,
            deep: 1,
            departments: {
                $map: {
                    input: "$departments",
                    as: 'department',
                    in: {
                            "code" : "$$department._id",
                            "department_field_1" : "$$department.department_field_1",
                            "department_field_2" : "$$department.department_field_2",
                            ...
                    }
                }
            },
            description: 1,
            employees: 1,
            name: 1,
            range: 1,
            skills: {
                $map: {
                    input: "$skills",
                    as: 'skill',
                    in: {
                            "code" : "$$skill._id",
                            "skill_field_1" : "$$skill.skill_field_1",
                            "skill_field_2" : "$$skill.skill_field_2",
                            ...
                    }
                }
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      这可能有助于from docs

      您可以在哪里使用 $replaceRoot 与嵌套在数组中的文档

      例如,如果您有这样的文件:

      {
            "_id" : 1,
            "grades" : [
               { "test": 1, "grade" : 80, "mean" : 75, "std" : 6 },
               { "test": 2, "grade" : 85, "mean" : 90, "std" : 4 },
               { "test": 3, "grade" : 95, "mean" : 85, "std" : 6 }
            ]
         },
         {
            "_id" : 2,
            "grades" : [
               { "test": 1, "grade" : 90, "mean" : 75, "std" : 6 },
               { "test": 2, "grade" : 87, "mean" : 90, "std" : 3 },
               { "test": 3, "grade" : 91, "mean" : 85, "std" : 4 }
            ]
         }
      

      以下操作将grade字段大于或等于90的嵌入文档提升到顶层:

      db.students.aggregate( [
         { $unwind: "$grades" },
         { $match: { "grades.grade" : { $gte: 90 } } },
         { $replaceRoot: { newRoot: "$grades" } }
      ] )
      

      给出输出

      { "test" : 3, "grade" : 95, "mean" : 85, "std" : 6 }
      { "test" : 1, "grade" : 90, "mean" : 75, "std" : 6 }
      { "test" : 3, "grade" : 91, "mean" : 85, "std" : 4 }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-18
        • 2017-05-19
        • 2014-11-03
        • 1970-01-01
        • 2023-01-04
        • 1970-01-01
        相关资源
        最近更新 更多