MongoDB位置$(更新)运算符错误

时间:2014-06-12 12:10:16

标签: mongodb

根据MongoDB documentation,$运算符可用于将内容更新为与查询文档匹配的嵌入式列表。我的例子比文档中的例子复杂一点:

db.item.insert({
    "_id" : ObjectId("5398786591846667374b8f7c"),
    "outputs" : [ 
        {
            "action" : "VIDEO",
            "portalType" : "FACEBOOK",
            "status" : 1
        }, 
        {
            "portalType" : "YOUTUBE",
            "action" : "VIDEO",
            "status" : 1
        }
    ]
})

现在我执行以下查询:

db.item.update(
{ _id: ObjectId('5398786591846667374b8f7c'),
    "outputs.portalType": "YOUTUBE",
    "outputs.action": "VIDEO" },
{ $set: { "outputs.$.status": NumberInt(99)}})

令人惊讶的是,结果是输出数组的第一个元素被修改(具有portalType = FACEBOOK的元素),根据我的查询肯定是错误的:"包含action = VIDEO 的输出 portalType = YOUTUBE"。

http://s16.postimg.org/dyf4fmi6d/Untitled.png


修改 要匹配数组中的多个标准并确保所有标准都匹配,应在update命令的查询部分中使用 $ elemMatch ,如 Neil Lunn

1 个答案:

答案 0 :(得分:0)

这确实按设计工作。

以下是数据:

{
    "_id" : ObjectId("5398786591846667374b8f7c"),
    "outputs" : [
            {
                    "action" : "VIDEO",
                    "portalType" : "FACEBOOK",
                    "status" : 1
            },
            {
                    "portalType" : "YOUTUBE",
                    "action" : "VIDEO",
                    "status" : 1
            }
    ]
}

以下是更新:

db.item.update(
   { 
        "_id": ObjectId("5398786591846667374b8f7c"),
        "outputs.portalType": "YOUTUBE",
        "outputs.action": "VIDEO"
   }, 
   { "$set": { "outputs.$.status": NumberInt(99) }}
)

结果如下:

{
    "_id" : ObjectId("5398786591846667374b8f7c"),
    "outputs" : [
            {
                    "action" : "VIDEO",
                    "portalType" : "FACEBOOK",
                    "status" : 1
            },
            {
                    "portalType" : "YOUTUBE",
                    "action" : "VIDEO",
                    "status" : 99
            }
    ]
}

也许这是你的问题,因为你的条件可能没有像你期望的那样:

db.item.update(
   { 
        "_id": ObjectId("5398786591846667374b8f7c"),
        "outputs": { 
            "$elemMatch": {
                "portalType": "YOUTUBE",
                "action": "VIDEO" 
            }
        }
   }, 
   { "$set": { "outputs.$.status": NumberInt(99) }}
)

因此$elemMatch确保数组项中存在两个条件,而前一个表单可能与数组的其他成员匹配。该匹配仅作为整体的“文档”。

所以这是try.mongodb.org输出: enter image description here

注意更新语句的最后一行和修改后的文档。