2015-09-28 58 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