在汇总MongoDB之后重命名字段

时间:2018-08-06 19:29:20

标签: mongodb

在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, 
      ....
    }
  ]
}

有没有办法在“代码”中替换子文档关键字“ _id”的名称?例如,我希望“ departments._id”为“ departments.code”。同样的技能。无论如何,如果有关系,我将使用MongoDB 3.6和PyMongo。 谢谢

3 个答案:

答案 0 :(得分:0)

从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"
}

答案 1 :(得分:0)

您也可以使用$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",
                        ...
                }
            }
        }
    }
}

答案 2 :(得分:0)

这可能会帮助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 }
      ]
   }

以下操作将等级字段大于或等于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 }