搜索后,我无法弄清楚如何对单个字段执行多个更新。
我有一个带有"标签的文件"数组字段。在开始更新之前,每个文档都会有随机标记。在单个操作中,我想添加一些标签并删除一些标签。
以下更新运算符返回错误"指定的无效修饰符:$和"
updateOperators: { "$and" : [
{ "$addToSet" : { "tags" : { "$each" : [ "tag_1" , "tag_2"]}}},
{ "$pullAll" : { "tags" : [ "tag_2", "tag_3"]}}]}
collection.update(query, updateOperators, multi=true)
如何在单个操作中向数组添加和删除值到多个文档?
答案 0 :(得分:2)
您不需要$and
更新查询,但是您无法同时使用更新更新两个字段 - 正如您在shell中尝试以下内容时所看到的那样:
db.test.update({}, { "$addToSet" : { "tags" : { "$each" : [ "tag_1" , "tag_2"]}},
"$pullAll" : { "tags" : [ "tag_2", "tag_3"] }}, true, false)
您会收到Cannot update 'tags' and 'tags' at the same time
错误消息。那么如何实现呢?使用此模式,您需要在多个操作中执行此操作,您可以使用新的bulk operation api,如下所示(shell):
var bulk = db.coll.initializeOrderedBulkOp();
bulk.find({ "tags": 1 }).updateOne({ "$addToSet": { "$each" : [ "tag_1" , "tag_2"]}});
bulk.find({ "tags": 1 }).updateOne({ "$pullAll": { "tags": [ "tag_2", "tag_3"] } });
bulk.execute();
或者在Casbah中使用dsl助手:
val bulk = collection.initializeOrderedBulkOperation
bulk.find(MongoDBObject("tags" -> 1)).updateOne($addToSet("tags") $each("tag_1", tag_2"))
bulk.find(MongoDBObject("tags" -> 1)).updateOne($pullAll("tags" -> ("tags_2", "tags_3")))
bulk.execute()
它不是原子的,并且不能保证没有其他任何东西会尝试修改,但它就像你现在所能得到的那样接近。
答案 1 :(得分:1)
Mongo进行原子更新,因此您可以在数组中构建所需的标记,然后替换整个数组。
我建议不要使用数组来存储这些值,因为这是一个"未绑定的"标签数组。未绑定的数组会导致磁盘上的移动,从而导致索引更新,操作系统和mongo可以正常工作。
相反,您应该将每个标记作为单独的文档存储在不同的集合中,并且#34; bucket"它们基于相关文件的_id。
示例
{_id : <_id> <key> <value>} - single docuemnt
这将允许您使用db.collection.find({_ id:/ ^&lt; _id&gt; /})查询单个用户的所有标记并将结果存储起来。