2015-01-13 59 views
0

如果我有以下文件只得到子元素

{ 
    "_id" : ObjectId("54986d5531a011bb5fb8e0ee"), 
    "owner" : "54948a5d85f7a9527a002917", 
    "type" : "group", 
    "deleted" : false, 
    "participants" : [ 
     { "_id": "54948a5d85f7a9527a002917", "name": "user1" }, 
     { "_id": "5491234568f7a9527a002918", "name": "user2" }, 
     { "_id": "5491234568f7a9527a002918", "name": "user3" }, 
     { "_id": "1234567aaaa7a9527a002917", "name": "user2" } 
    ] 
} 

我怎麼會得到所有記錄,其中名稱=「用戶2」?

我嘗試followoing:

db.users.find({ _id: ObjectId('54a7103b1a57eee00bc0a9e4') }, 
{ 'participants.$.name': 'user2') }).pretty() 

...我得到如下:

error: { 
    "$err" : "Can't canonicalize query: BadValue Positional projection 'participants.$.name' does not match the query document.", 
    "code" : 17287 
} 

回答

0

雖然定位符($)會給你從第一個匹配的元素參與者數組。如果您需要名稱爲user2的所有參與者,則需要彙總結果。

  • Match該文件與所需的_id

  • 使用redact運營商只保留 參與者,其名稱爲user2的所有子文檔。

代碼:

var search = "user2"; 
db.users.aggregate([ 
{$match:{"_id":ObjectId("54986d5531a011bb5fb8e0ee")}}, 
{$redact:{$cond:[{$eq:[{$ifNull:["$name",search]},search]}, 
       "$$DESCEND", 
       "$$PRUNE"]}}, 
{$project:{"participants":1,"_id":0}} // set _id:1, if you need the _id. 
]) 

O/P:

{ 
     "participants" : [ 
       { 
         "_id" : "5491234568f7a9527a002918", 
         "name" : "user2" 
       }, 
       { 
         "_id" : "1234567aaaa7a9527a002917", 
         "name" : "user2" 
       } 
     ] 
} 

來到查詢,

​​

的位置操作者可以只在陣列上被施加,這在find函數的查詢文檔中被引用。上述查詢文檔沒有引用名爲participants的數組,並且僅引用_id字段來匹配文檔。因此你會得到錯誤。

docs

領域的限制必須出現在查詢文檔

中那麼,更改查詢,包括查詢文件將修復該錯誤參與者陣列。

db.users.find({ "_id":ObjectId('54a7103b1a57eee00bc0a9e4'), 
        "participants.name": "user2" 
       }, 
       {"participants.$.name":"user2"}).pretty() 

但它只會返回與查詢文檔中的條件匹配的第一個參與者。

docs,在find()方法或findOne() 方法時,你只需要選擇 文件一個特定的數組元素的投影文檔中

使用$。

O/P:

{ 
     "_id" : ObjectId("54986d5531a011bb5fb8e0ee"), 
     "participants" : [ 
       { 
         "_id" : "5491234568f7a9527a002918", 
         "name" : "user2" 
       } 
     ] 
}