MongoDB 通过 Id 数组删除嵌入文档

Ven*_*son 5 mongoose mongodb

我正在开发一个Node.js使用MongooseMongoDB数据库的应用程序。我一直被困在这件事上,没有提出正确的查询。

问题:

有一个名为的集合,其中包含作为对象数组的chats嵌入文档。(rooms)我想删除数组中的(rooms)这些嵌入文档。Ids

  {
    "_id": "ObjectId(6138e2b55c175846ec1e38c5)",
    "type": "bot",
    "rooms": [
      {
        "_id": "ObjectId(6138e2b55c145846ec1e38c5)",
        "genre": "action"
      },
      {
        "_id": "ObjectId(6138e2b545c145846ec1e38c5)",
        "genre": "adventure"
      }
    ]
  },
  {
    "_id": "ObjectId(6138e2b55c1765846ec1e38c5)",
    "type": "person",
    "rooms": [
      {
        "_id": "ObjectId(6138e2565c145846ec1e38c5)",
        "genre": "food"
      },
      {
        "_id": "ObjectId(6138e2b5645c145846ec1e38c5)",
        "genre": "sport"
      }
    ]
  },
  {
    "_id": "ObjectId(6138e2b55c1765846ec1e38c5)",
    "type": "duo",
    "rooms": [
      {
        "_id": "ObjectId(6138e21c145846ec1e38c5)",
        "genre": "travel"
      },
      {
        "_id": "ObjectId(6138e35645c145846ec1e38c5)",
        "genre": "news"
      }
    ]
  }
Run Code Online (Sandbox Code Playgroud)

我正在将我的数组转换ids为 MongoDB ObjectId,这样我就可以使用这些 id 作为匹配条件。

const idsRoom = [
  '6138e21c145846ec1e38c5',
  '6138e2565c145846ec1e38c5',
  '6138e2b545c145846ec1e38c5',
];

const objectIdArray = idsRoom.map((s) => mongoose.Types.ObjectId(s));
Run Code Online (Sandbox Code Playgroud)

并将此查询用于聊天集合。但它正在删除整个文档,我只想删除rooms嵌入文档,因为 ids 数组仅用于嵌入文档。

Chat.deleteMany({ 'rooms._id': objectIdArray }, function (err) {
  console.log('Delete successfully')
})
Run Code Online (Sandbox Code Playgroud)

我非常感谢您在这个问题上的帮助。

J.F*_*.F. 2

您必须在查询中使用$pull运算update符,如下所示:

此查询查找数组中存在的文档_idrooms并用于$pull从数组中删除对象。

yourModel.updateMany({
  "rooms._id": {
    "$in": [
      "6138e21c145846ec1e38c5",
      "6138e2565c145846ec1e38c5",
      "6138e2b545c145846ec1e38c5"
    ]
  }
},
{
  "$pull": {
    "rooms": {
      "_id": {
        "$in": [
          "6138e21c145846ec1e38c5",
          "6138e2565c145846ec1e38c5",
          "6138e2b545c145846ec1e38c5"
        ]
      }
    }
  }
})
Run Code Online (Sandbox Code Playgroud)

例子在这里

您也可以像这样运行不带参数的查询query(在更新查询中,第一个对象是query),结果是相同的。但最好使用第一个对象来指示 mongo 文档。