2013-08-01 81 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 } ] }