根据this answer,通过索引从数组中删除元素意味着两个不同的更新:
db.lists.update({}, {$unset : {"interests.0" : 1 }})
db.lists.update({}, {$pull : {"interests" : null}})
这有效......但它引入了一些复杂性,使操作成为原子并防止竞争条件。该主题是否有任何更新?
答案 0 :(得分:1)
是的,不,真的。请考虑以下数组:
{ array: [ { a: "a", b: "b" }, { a:"a", b:"c" } ] }
所以你可以$pull使用以下语句从这里开始第二个元素:
db.collection.update({}, {$pull: { array: { a: "a", b: "b"} } })
这将删除匹配的文档。但如果在这个阵列上做同样的事情:
{ array: [ { a: "a", b: "b" }, { a: "a", b:"c", c: "c" }, { a:"a", b:"c" } ] }
然后这就是结果:
{ array: [ { a: "a", b: "b" }] }
所以查询匹配了数组中的两个文档,并将它们都拉出来。
不幸的是,这看似很明显: db.collection.update({}, {$pull: { array: { $elemMatch:{ a: "a", b: "b" } }} })
只是不会工作。哪个是遗憾。在太难的篮子中,此时要解析。
故事的寓意是,如果你真的关注此类更新的并发性和竞争条件,首先是 .find()
匹配元素, 然后 update()
,其语句与整个文档相匹配,只要它不也是部分匹配数组中的另一个文档。
如果你不能这样做,那么你在问题中描述的方法是目前唯一的方法。
有一个JIRA问题,但它并不是非常受欢迎。