Mongodb 我可以使用聚合框架轻松地将子文档的所有字段作为顶级文档中的字段返回吗?

Mongodb 我可以使用聚合框架轻松地将子文档的所有字段作为顶级文档中的字段返回吗?,mongodb,mongodb-query,Mongodb,Mongodb Query,我有一个类似于以下的文档,我想从中返回当前顶级字段的子字段,作为结果数组的每个文档中的顶级字段: { field1: { subfield1: {}, subfield2: [], subfield3: 44, subfield5: xyz }, field2: { othercontent: {} } } 我希望聚合查询的结果返回以下内容(作为顶级文档的field1的内容): 使用$project和聚合框架是否可以在不定义每个子字段作

我有一个类似于以下的文档,我想从中返回当前顶级字段的子字段,作为结果数组的每个文档中的顶级字段:

{ 
  field1: {
    subfield1: {},
    subfield2: [],
    subfield3: 44,
    subfield5: xyz
  },
  field2: {
    othercontent: {}
  }
}
我希望聚合查询的结果返回以下内容(作为顶级文档的
field1
的内容):


使用
$project
和聚合框架是否可以在不定义每个子字段作为顶级字段返回的情况下实现这一点?

通常很难让MongoDB处理不明确或参数化的json键。我遇到了一个问题,最好的解决方案是修改模式,使子文档的成员成为数组中的元素

然而,我认为这将使您接近您想要的(所有代码都应该直接在Mongo shell中运行)。假设您拥有以下文档:

db.collection.insert({
  "_id": "doc1",
  "field1": {
           "subfield1": {"key1": "value1"},
           "subfield2": ["a", "b", "c"],
           "subfield3": 1,
           "subfield4": "a"
         },
  "field2": "other content"
})

db.collection.insert({ 
  "_id": "doc2",
  "field1": {
           "subfield1": {"key2": "value2"},
           "subfield2": [1, 2, 3],
           "subfield3": 2,
           "subfield4": "b"

         },
  "field2": "yet more content"
})
然后,您可以运行一个聚合命令来提升
field1
的内容,同时忽略文档的其余部分:

{
  subfield1: {},
  subfield2: [],
  subfield3: 44,
  subfield5: xyz
}
db.collection.aggregate({
"$group":{
    "_id": "$_id",
    "value": {"$push": "$field1"}
}})
这使得所有的
子字段*
键进入一个对象的顶级字段,而该对象是数组中唯一的元素。这很笨拙,但可行:

"result" : [
        {
                "_id" : "doc2",
                "value" : [
                        {
                                "subfield1" : {"key2" : "value2"},
                                "subfield2" : [1, 2, 3],
                                "subfield3" : 2,
                                "subfield4" : "b"
                        }
                ]
        },
        {
                "_id" : "doc1",
                "value" : [
                        {
                                "subfield1" : {"key1" : "value1"},
                                "subfield2" : ["a","b","c"],
                                "subfield3" : 1,
                                "subfield4" : "a"
                        }
                ]
        }
],
"ok" : 1
从3.4开始,您可以使用聚合运算符:

db.getCollection('sample').aggregate([
    {
        $replaceRoot: {newRoot: "$field1"}
    }
])
按预期提供输出:

{
    "subfield" : {},
    "subfield2" : [],
    "subfield3" : 44,
    "subfield5" : "xyz"
}

Mongo 4.2
开始,可以使用聚合运算符将一个文档替换为另一个文档(在本例中为子文档),作为
$replaceRoot
的同义词:

// { field1: { a: 1, b: 2, c: 3 }, field2: { d: 4, e: 5 } }
// { field1: { a: 6, b: 7 }, field2: { d: 8 } }
db.collection.aggregate({ $replaceWith: "$field1" })
// { a: 1, b: 2, c: 3 }
// { a: 6, b: 7 }

我很好奇这是否可能;我倾向于认为不是。这个问题似乎相关:这不符合问题的要求。输出文档的形状不同。