2015-09-28 60 views
1

我試圖推送到MongoDB 3.0.4中的嵌套數組。這將說明problem-這裏是在字符集的文件,我想IMAGE_4添加到埃爾默的圖像陣列:

{ 
    "_id" : ObjectId("56084e91981824fc51693e72"), 
    "firstname" : "Elmer", 
    "lastname" : "Fudd", 
    "company" : "Warners", 
    "password" : "4567", 
    "galleries" : [ 
     { 
      "gallery" : "1", 
      "images" : [ 
       "image_1", 
       "image_2", 
       "image_3" 
      ] 
     } 
    ] 
} 

首先我想:

db.characters.update({"firstname":"Elmer"},{$push {"galleries.$.images":"image_4"}}) 

,並得到了錯誤:

"writeError" : { 
     "code" : 16837, 
     "errmsg" : "The positional operator did not find the match needed from the query. Unexpanded update: galleries.$.images" 

然後我看到了SO Update an item in an array that is in an array 的解決方案,並試圖:

db.characters.update({"firstname":"Elmer"},{$push:{"galleries.0.images":"image_4"}}) 

哪些工作正常。我知道位置操作符$不能用於嵌套數組,但爲什麼用0代替它,在這種用法中什麼是0?我無法在Mongodb文檔中找到它。

+0

錯誤是非常具有描述性的,你不匹配數組的一個元素。因此,請在您的更新的查詢部分中使用:{{「firstname」:「Elmer」,「galleries.gallery」:1}',以便實際匹配所需的元素。 –

+0

@Blakes七。 db.characters.update({「firstname」:「Elmer」,「galleries.gallery」:1},{$ push:{「images」:「image_4」}})不起作用。沒有錯誤信息,但nModified:0。 – meanstacky

+0

因爲那時你根本沒有使用位置'$'操作符。爲了使用位置運算符,您需要匹配數組中的元素,然後在更新部分中指定運算符。只要改變你寫的第一個查詢,也包含數組元素的匹配。 –

回答

0

在這種用法,0將轉化

The first element of the 0 based array stored in the galleries field of the first document in which the field firstname equals "Elmar".

這當然在這種情況下工作。但是,數組不能保證以每個查詢的相同順序返回。所以如果你有兩個畫廊,畫廊1可以作爲第二個數組元素返回。

這裏的問題是您的查詢並未真正反映您想要做什麼。你真正想做的是

In the document in which the field firstname equals "Elmar", add "img_4" to the array element in galleries in which the field gallery equals 1.

那麼,我們將如何實現這一目標?基本上,您使用$運營商的方式正確。但是,您的查詢不包含數組的匹配模式,這是強制性的(查詢引擎如何識別更新的確切數組元素)。所以,你的查詢需要修改一下:

db.characters.update(
    // The query part 
    { 
    // Nothing new here 
    "firstname": "Elmar", 
    // Now we want to identify the gallery: 
    // "Of all elements in the galleries array..." 
    "galleries": { 
     // "...find the element..." 
     "$elemMatch":{ 
     // "...in which the field gallery equals 1." 
     "gallery": "1" 
     } 
    } 
    }, 
    // Update part 
    { 
    // You want to use $addToSet instead of $push here 
    // since you don't want to have an image twice in a gallery 
    "$addToSet":{ 
     // $ operator works now since we have identified the gallery 
     // in the query part 
     "galleries.$.images":"image_4" 
    } 
    } 
) 

請看看在docs for the positional $ parameter瞭解詳情。

備註:截至本文寫作時,BSON文檔的文檔大小限制爲16MB,因此您可能應該重新考慮您的模型。但是,這是一個不同的故事(如何在MongoDB中正確建模多對多關係,之前已經有過百萬次的感受)。

+0

謝謝你的清晰簡潔的解釋。它幫助了很多。 – meanstacky