Mongodb Update/Upsert 数组完全匹配



我有一个集合:

gStats : {
     "_id" : "id1",
     "criteria" : ["key1":"value1", "key2":"value2"],
     "groups" : [
             {"id":"XXXX", "visited":100, "liked":200},
             {"id":"YYYY", "visited":30, "liked":400}
     ]
}

我希望能够更新给定条件数组的统计信息数组的文档(完全匹配(。

我尝试通过 2 个步骤执行此操作:

从给定"id"的数组中提取统计文档:

db.gStats.update({
    "criteria" : {$size : 2},
    "criteria" : {$all : [{"key1" : "2096955"},{"value1" : "2015610"}]}
},
{
    $pull : {groups : {"id" : "XXXX"}}
}
)

推送新文档

db.gStats.findAndModify({
    query : {
        "criteria" : {$size : 2},
        "criteria" : {$all : [{"key1" : "2015610"}, {"key2" : "2096955"}]}
    },
    update : {
        $push : {groups : {"id" : "XXXX", "visited" : 29, "liked" : 144}}
    },
    upsert : true
})

拉取查询工作完美。推送查询给出错误:

2014-12-13T15:12:58.571+0100 findAndModifyFailed failed: {
        "value" : null,
        "errmsg" : "exception: Cannot create base during insert of update. Cause
d by :ConflictingUpdateOperators Cannot update 'criteria' and 'criteria' at the
same time",
        "code" : 12,
        "ok" : 0
} at src/mongo/shell/collection.js:614

这两个查询在现实中都不起作用。您不能多次使用像"criteria"这样的键名,除非在某$and运算符下。您还将指定不同的字段(即组(并查询示例文档中不存在的元素。

很难说出你在这里真正想做什么。但是错误基本上是由我提到的第一个问题引起的,还有一些额外的东西。因此,实际上您的{ "$size": 2 }条件被忽略了,只应用了第二个条件。

有效的查询表单应如下所示:

query: {
    "$and": [
        { "criteria" : { "$size" : 2 } },
        { "criteria" : { "$all": [{ "key1": "2015610" }, { "key2": "2096955" }] } }
    ]
}

由于每组条件都是在$and提供的数组中指定的,因此查询的文档结构是有效的,并且没有覆盖另一个的哈希键名称。这是编写两个条件的正确方法,但是有一个技巧可以使这项工作,其中"upsert"由于这些条件与文档不匹配而失败。当它试图在创建时应用$all参数时,我们需要覆盖正在发生的事情:

update: {
    "$setOnInsert": {
        "criteria" : [{ "key1": "2015610" }, { "key2": "2096955" }]
    },
    "$push": { "stats": { "id": "XXXX", "visited": 29, "liked": 144 } }
}

这使用 $setOnInsert 这样,当应用"upsert"并且新文档创建时,将使用此处指定的条件,而不是使用语句的查询部分中设置的字段值。

当然,如果您真正要查找的内容确实与数组中的内容完全匹配,那么只需将其用于查询:

query: {
    "criteria" : [{ "key1": "2015610" }, { "key2": "2096955" }]
}

然后,MongoDB将很乐意在创建新文档时应用这些值,并且不会对如何解释$all表达式感到困惑。

最新更新