【问题标题】:Project nested document to root level without using $project不使用 $project 将嵌套文档投影到根级别
【发布时间】:2019-05-08 09:52:00
【问题描述】:

使用聚合管道,我试图将嵌入文档投影到根级别,而不单独投影每个字段,也无需替换根级别。

例如,我想将这个集合投影到根级别:

[
    {
        _id: "1",
        city: "NY"
        user: [ {
            firstName: "John",
            lastname: "Peters",
            brothers: [
                { _id: "B1",
                  brotherFirstName: "Karl" }
            ]
         }, {
            firstName: "Raul",
            lastname: "Other",
            brothers: [
                { _id: "B2",
                  brotherFirstName: "May" }
            ]
         }, {
            firstName: "Paul",
            lastname: "Ray",
            brothers: [
                { _id: "B3",
                  brotherFirstName: "Bryan" }
            ]
         }        
    },
    {
        _id: "2",
        city: "NY"
        user: [ {
            firstName: "Joe",
            lastname: "Anders",
            brothers: [
                { _id: "B4",
                  brotherFirstName: "Carla" }
            ]
         }, {
            firstName: "Zoy",
            lastname: "Bat",
            brothers: [
                { _id: "B5",
                  brotherFirstName: "Stuart" }
            ]
         }, {
            firstName: "Ana",
            lastname: "Lily",
            brothers: [
                { _id: "B6",
                  brotherFirstName: "Carter" }
            ]
         }        
    }
]

这就是我要查找的内容:对于子文档数组中的每个文档,我想将其投影到根级别,因此对于每个“用户”我想将它投影到“新文档”和每个“兄弟”我想要将其投影到“新文档”

[{
  _id: "1",
  city: "NY"
  firstName: "John",
  lastname: "Peters",
  brotherFirstName: "Karl" 
}, { 
  _id: "1",
  city: "NY"
  firstName: "Raul",
  lastname: "Other",
  brotherFirstName: "May" 
}, {
  _id: "1",
  city: "NY"
  firstName: "Paul",
  lastname: "Ray",
  brotherFirstName: "Bryan" 
}, {
  _id: "2",
  city: "NY"
  firstName: "Joe",
  lastname: "Anders",
  brotherFirstName: "Carla"
 }, {
  _id: "2",
  city: "NY"
  firstName: "Zoy",
  lastname: "Bat",
  brotherFirstName: "Stuart"
 }, {
  _id: "2",
  city: "NY"
  firstName: "Ana",
  lastname: "Lily",
  brotherFirstName: "Carter"
 }        
]

我尝试聚合 $unwind e $replaceRoot,但我无法“替换根”,因为我需要这些字段

db.getCollection('myColl').aggregate([  { $unwind : "$users" },  {$replaceRoot: { newRoot: "$users" }}, {$unwind : "$brothers" } ])

编辑

运行@Anthony Winzlet 查询我有这个输出:

[
  {
    "_id": "B1",
    "brotherFirstName": "Karl",
    "city": "NY",
    "firstName": "John",
    "lastname": "Peters"
  },
  {
    "_id": "B2",
    "brotherFirstName": "May",
    "city": "NY",
    "firstName": "Raul",
    "lastname": "Other"
  },
  {
    "_id": "B3",
    "brotherFirstName": "Bryan",
    "city": "NY",
    "firstName": "Paul",
    "lastname": "Ray"
  },
  {
    "_id": "B4",
    "brotherFirstName": "Carla",
    "city": "NY",
    "firstName": "Joe",
    "lastname": "Anders"
  },
  {
    "_id": "B5",
    "brotherFirstName": "Stuart",
    "city": "NY",
    "firstName": "Zoy",
    "lastname": "Bat"
  },
  {
    "_id": "B6",
    "brotherFirstName": "Carter",
    "city": "NY",
    "firstName": "Ana",
    "lastname": "Lily"
  }
]

_id 字段被兄弟的 _id 字段覆盖。我需要来自根目录的项目 _id

【问题讨论】:

    标签: javascript mongodb mongodb-query aggregation-framework


    【解决方案1】:

    您需要在 $$ROOT 文档中使用$mergeObjects。首先使用user,其次使用brother,最后你必须使用$project 删除userbrother 对象

    db.collection.aggregate([
      { "$unwind": "$user" },
      { "$replaceRoot": {
        "newRoot": { "$mergeObjects": ["$$ROOT", "$user"] }
      }},
      { "$unwind": "$brothers" },
      { "$replaceRoot": {
        "newRoot": { "$mergeObjects": ["$brothers", "$$ROOT"] }
      }},
      { "$project": { "brothers": 0, "user": 0 }}
    ])
    

    Output

    [
      {
        "_id": "1",
        "brotherFirstName": "Karl",
        "city": "NY",
        "firstName": "John",
        "lastname": "Peters"
      },
      {
        "_id": "1",
        "brotherFirstName": "May",
        "city": "NY",
        "firstName": "Raul",
        "lastname": "Other"
      },
      {
        "_id": "1",
        "brotherFirstName": "Bryan",
        "city": "NY",
        "firstName": "Paul",
        "lastname": "Ray"
      },
      {
        "_id": "2",
        "brotherFirstName": "Carla",
        "city": "NY",
        "firstName": "Joe",
        "lastname": "Anders"
      },
      {
        "_id": "2",
        "brotherFirstName": "Stuart",
        "city": "NY",
        "firstName": "Zoy",
        "lastname": "Bat"
      },
      {
        "_id": "2",
        "brotherFirstName": "Carter",
        "city": "NY",
        "firstName": "Ana",
        "lastname": "Lily"
      }
    ]
    

    【讨论】:

    • 太好了!但我有一个问题。父元素的 _id 字段被子元素 _id 字段的值覆盖。某些字段在父元素和子元素中具有相同的名称。有没有办法选择我想在哪个字段中保留值?
    • 好的,用新的样本集合和输出更新您的问题。然后我就可以看到了。
    • 我编辑了我的问题。我在docs.mongodb.com/manual/reference/operator/aggregation/… 上读到,mergeobject 会覆盖相同的字段名称。我可以在 mergeObjects 之前投影或隐藏论文字段吗?
    • @Alberto 更新了我的答案
    • @Alberto 再次更新了我的答案。将$$ROOT 保留在$mergeObjects 的第二个表达式中
    猜你喜欢
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多