0

我的结构如下所示:

{
  field1: "somevalue",
  name:"xtz",
  nested_documents: [ 
                        {   
                            x:1,
                            y:2,
                            info:[
                                    {name:"sachin",value:"test"},
                                    {name:"sachin", value:"test"}
                                 ]
                        },
                        {
                            x:1,
                            y:3,
                            info:[
                                    {name:"sachin1",value:"test"},
                                    {name:"sachin2", value:"test"}
                                 ]
                        },
                        {
                            x:4,
                            y:3,
                            info:[
                                    {name:"sachin",value:"test"},
                                    {name:"sachin", value:"test"}
                                 ]
                        }
                    ]
    }

我知道我可以使用以下代码检索第一个数组中存在的元素:

db.test.find({"nested_documents.x": 1},{_id: 0, nested_documents: {$elemMatch: {x: 1}}}

但是,我想对name属性应用相同的逻辑。我只想检索名称为“sachin”的文档。我尝试的内容如下所示:

db.test.find({"nested_documents.info.name": "sachin"}, 
        {_id: 0, 'nested_documents.info': {$elemMatch: {name: "sachin"}}});

但是Mongo db说它不支持'。投影内的运算符:(。
还有其他方法可以做到这一点吗?(使用命令提示符或代码)

插入文档的命令如下所示:

db.test.insert( {
  field1: "somevalue",
  name:"xtz",
  nested_documents: [ 
                        {   
                            x:1,
                            y:2,
                            info:[
                                    {name:"sachin",value:"test"},
                                    {name:"sachin", value:"test"}
                                 ]
                        },
                        {
                            x:1,
                            y:3,
                            info:[
                                    {name:"sachin1",value:"test"},
                                    {name:"sachin2", value:"test"}
                                 ]
                        },
                        {
                            x:4,
                            y:3,
                            info:[
                                    {name:"sachin",value:"test"},
                                    {name:"sachin", value:"test"}
                                 ]
                        }
                    ]
    }
    )

我期望输出为:

{ "_id" : ObjectId("5142e0f153cd2aab3a3bae5b"), 
"nested_documents" : [ 
                        {       "x" : 1,        "y" : 2,       
                        "info" : [     
                                    {       "name" : "sachin",      "value" : "test" },   
                                    {       "name" : "sachin",      "value" : "test" } 
                                ] 
                        },
                        {      "x" : 4,        "y" : 3,        
                        "info" : [      {       "name" : "sachin",      "value" : "test" },
                                        {       "name" : "sachin",      "value" : "test" } 
                                ] 
                        } 
                    ]
}
4

1 回答 1

0

您必须将 aggregate() 与双 $unwind 一起使用,如下所示:

db.test.aggregate([
    // filter for documents with x=1
    // note: this will use an index, if defined on "nested_documents.x"
    //{ $match: { "nested_documents.x": 1 } },
    // reduce data to nested_documents, as other fields are not considered
    { $project: { nested_documents: 1 } },
    // flatten the outer array
    { $unwind: "$nested_documents" },
    // filter for nested_documents with x=1
    // note that at this point nested_documents is no longer an array
    //{ $match: { "nested_documents.x": 1 } },
    // flatten the inner array
    { $unwind: "$nested_documents.info" },
    // filter for nested_documents.info.name = "sachin"
    // note that at this point nested_documents.info is no longer an array
    { $match: { "nested_documents.info.name": "sachin" } },
    // format output: re-create inner array
    { $group: { _id: { id: "$_id", 
                       nested_documents: { 
                          x: "$nested_documents.x",
                          y: "$nested_documents.y" 
                       }
                     }, 
                     info: { $push: "$nested_documents.info" } } },
    { $project: { "nested_documents.x": "$_id.nested_documents.x",
                  "nested_documents.y": "$_id.nested_documents.y",
                  "nested_documents.info": "$info" } },
    // format output: re-create outer array
    { $group: { _id: "$_id.id", nested_documents: { $push: "$nested_documents" } } },
])

注意:我在 //comments 中输入了过滤 x=1 的逻辑,就像在前面的示例中一样

结果是:

{
    "result" : [
        {
            "_id" : ObjectId("515d873457a0887a97cc8d19"),
            "nested_documents" : [
                {
                    "x" : 4,
                    "y" : 3,
                    "info" : [
                        {
                            "name" : "sachin",
                            "value" : "test"
                        },
                        {
                            "name" : "sachin",
                            "value" : "test"
                        }
                    ]
                },
                {
                    "x" : 1,
                    "y" : 2,
                    "info" : [
                        {
                            "name" : "sachin",
                            "value" : "test"
                        },
                        {
                            "name" : "sachin",
                            "value" : "test"
                        }
                    ]
                }
            ]
        }
    ],
    "ok" : 1
}

有关聚合的更多信息,请参阅http://docs.mongodb.org/manual/applications/aggregation/

于 2013-04-04T15:18:31.857 回答