2013-08-01 83 views
0

我没有代码显示,因为我不知道如何实现我想要的。从Mongodb检索一个子文档

我读过,有可能从文档中返回一个子文档,但我还没有发现如何实际做到这一点。一个用户收藏的一个人为的例子:

[ 
    { 
     "_id":0, 
     "Name":"Person 1", 
     "Cupboard":[ 
     { 
      "_id":0, 
      "Items":[ 
       { 
        "_id":1, 
        "Name":"item 1" 
       }, 
       { 
        "_id":2, 
        "Name":"item 2" 
       } 
      ] 
     } 
     ] 
    } 
    , 
    { 
     "_id":1, 
     "Name":"Person 2", 
     "Cupboard":[ 
     { 
      "_id":0, 
      "Items":[ 
       { 
        "_id":1, 
        "Name":"item 1" 
       }, 
       { 
        "_id":2, 
        "Name":"item 2" 
       } 
      ] 
     } 
     ] 
    } 
] 

我怎么只能从橱柜返回项目,假设我知道柜子的_id?我正在使用C#驱动程序,但即使在mongo shell中执行此操作也很有用。

回答

1

所有你需要做的只是你想要的字段project。如果你想返回许多Items可以使用聚合框架的$unwind项目中的子项的查询结果

db.collection.find({ ... }, { 'Cupboard.Items' : 1, _id : 0 }) 
+0

这不会返回只投影'Cupboard.Items'数组的文档数组吗? – sambomartin

+0

虽然这将返回父文档减字段,所以不是技术上只返回项目,我倾向于将此标记为答案,因为我根本不明白下面答案中的$ unwind/$项目... –

+0

@SamDelaney尝试'db.Users.aggregate({$ unwind:“$ Cupboard”},{$ unwind:“$ Cupboard.Items”},{$ project:{_id:“$ Cupboard.Items._id”,Name:“$ Cupboard .Items.Name“}})'这将展开嵌套的项目数组并投影一个匹配'Items'子文档的文档数组 – sambomartin

0

:所以你的数据集,从橱柜里只返回项目将。

http://docs.mongodb.org/manual/reference/aggregation/unwind/

然后使用$project返回的Items

结果确保您使用$match运营商利用索引的管道早期筛选结果。

您可以创建一个管道作为BsonDocument。这里有一个例子:

var match = new BsonDocument 
      { 
       { 
        "$match", 
        new BsonDocument 
         { 
          {"Cupboard.Items._id", 123} 
         } 
       } 
      }; 

var match2 = new BsonDocument 
      { 
       /* other pipeline op */ 
      }; 

var pipeline = new[] { match, match2 }; 
var result = coll.Aggregate(pipeline); 

然而,如果你想要回User文件(或部分),其中一个孩子Item匹配特定的标准,你可以简单的使用发现。

db.Users.find({'Cupboard.Items._id':1234})

希望帮助

0

你可以做类似

> db.users.find({"Cupboard._id": 0}, {"Cupboard.$" : 1}).pretty() 

将返回

{ 
     "_id" : 0, 
     "Cupboard" : [ 
       { 
         "_id" : 0, 
         "Items" : [ 
           { 
             "_id" : 1, 
             "Name" : "item 1" 
           }, 
           { 
             "_id" : 2, 
             "Name" : "item 2" 
           } 
         ] 
       } 
     ] 
} 
{ 
     "_id" : 1, 
     "Cupboard" : [ 
       { 
         "_id" : 0, 
         "Items" : [ 
           { 
             "_id" : 1, 
             "Name" : "item 1" 
           }, 
           { 
             "_id" : 2, 
             "Name" : "item 2" 
           } 
         ] 
       } 
     ] 
} 
> 

但让周围改变我们的文件,使我们有以下,以便我们的用户拥有多个橱柜和其中一些不同的项目也是

> db.users.find().pretty() 
{ 
     "_id" : 0, 
     "Name" : "Person 1", 
     "Cupboard" : [ 
       { 
         "_id" : 0, 
         "Items" : [ 
           { 
             "_id" : 1, 
             "Name" : "item 1" 
           }, 
           { 
             "_id" : 2, 
             "Name" : "item 2" 
           } 
         ] 
       }, 
       { 
         "_id" : 1, 
         "Items" : [ 
           { 
             "_id" : 1, 
             "Name" : "item 1" 
           }, 
           { 
             "_id" : 2, 
             "Name" : "item 2" 
           } 
         ] 
       } 
     ] 
} 
{ 
     "_id" : 1, 
     "Name" : "Person 2", 
     "Cupboard" : [ 
       { 
         "_id" : 0, 
         "Items" : [ 
           { 
             "_id" : 1, 
             "Name" : "item 1" 
           }, 
           { 
             "_id" : 2, 
             "Name" : "item 2" 
           } 
         ] 
       }, 
       { 
         "_id" : 2, 
         "Items" : [ 
           { 
             "_id" : 21, 
             "Name" : "item 1" 
           }, 
           { 
             "_id" : 22, 
             "Name" : "item 2" 
           } 
         ] 
       } 
     ] 
} 

我们现在可以列出用户的所有橱柜。

db.users.aggregate([ 
    {$match: {"Cupboard._id": 0}}, 
    {$project: {"Cupboard._id": 1}} 
]) 

{ "_id" : 0, "Cupboard" : [ { "_id" : 0 }, { "_id" : 1 } ] } 
{ "_id" : 1, "Cupboard" : [ { "_id" : 0 }, { "_id" : 2 } ] }