我的 mongodb 中有以下对象:
{
"item": {
"id": "/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8=",
"status": {
"likes": [
"HU0HKFoL2YQuQ2WrYhj0rYoFbRkwJ0EJEf4ML7vAp2Q="
]
}
}
}
现在我想更新我的集合,并从集合中所有在 item.status.liles
数组中包含此值的文档中提取值“/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8=”。
当我使用Robo 3T工具时,我可以放入命令行:
db.getCollection('mycollection').update({"item.status.likes": "/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8=" }, { "$pull":{"item.status.likes": "/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8="}})
当我执行命令时它显示 Updated 0 record(s) in 2ms
(这是正确的,因为没有匹配的文档)。
现在当我在 Node.JS 代码中做同样的事情时,就像这样:
let filter = {item.status.likes: '/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8='};
let obj = {"$pull":{"item.status.likes":"/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8="}}
collection.updateMany(filter, obj, { upsert: true }, (err, info) => {...});
我得到了 MongoError: Cannot apply $pull to a non-array value
。
如果我把它改成:
collection.updateMany({}, obj, { upsert: true }, (err, info) => {...});
我没有发现错误。这让我相信“无过滤器”和“空结果集”之间存在差异,而 $pull 对后者不起作用。
这是为什么?我还尝试了不同的“$pull”-语法(例如 {"item":{"status":{"likes"...
与 item.status.likes
),但这并没有改变任何东西。
答案 0 :(得分:1)
由于 upsert: true
导致没有单个文档与过滤器匹配时会发生错误。
它告诉 mongo 插入一个包含来自过滤器的字段的新文档,从而生成以下文档:
{
"item": {
"status": {
"likes": "/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8="
}
}
}
然后它尝试将更新应用到此文档,对导致错误的字符串调用 $pull。
Robo3T 版本有效,因为默认更新为 upsert: false
。