数组属性上的“updateMany”和“$pull”问题

问题描述

我的 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({},info) => {...});

我没有发现错误。这让我相信“无过滤器”和“空结果集”之间存在差异,而 $pull 对后者不起作用。

这是为什么?我还尝试了不同的“$pull”-语法(例如 {"item":{"status":{"likes"...item.status.likes),但这并没有改变任何东西。

解决方法

由于 upsert: true 导致没有单个文档与过滤器匹配时会发生错误。

它告诉 mongo 插入一个包含来自过滤器的字段的新文档,从而生成以下文档:

{ 
  "item": {
    "status": {
      "likes": "/Ed/6wigZ9LTLs2mPDWDzOFD/he0vbUEvQBl2Bga/T8="
    }
  }
}

然后它尝试将更新应用到此文档,对导致错误的字符串调用 $pull。

Robo3T 版本有效,因为默认更新为 upsert: false