【问题标题】:Using MongoDB $pull to delete documents within an Array使用 MongoDB $pull 删除数组中的文档
【发布时间】:2013-02-13 19:56:14
【问题描述】:

我在 MongoDB 中有一个集合,如下所示:

{
    "_id" : "5327010328645530500",
    "members" : [
        {
            "participationCoeff" : 1,
            "tweetID" : "5327010328645530500"
        },
        {
            "participationCoeff" : 1,
            "tweetID" : "2820402625046999289"
        },
        {
            "participationCoeff" : 0.6666666666666666,
            "tweetID" : "6122060484520699114"
        },
        {
            "participationCoeff" : 1,
            "tweetID" : "4656669980325872747"
        }
    ]
}
{
    "_id" : "2646953848367646922",
    "members" : [
        {
            "participationCoeff" : 1,
            "tweetID" : "2646953848367646922"
        },
        {
            "participationCoeff" : 0.75,
            "tweetID" : "7750833069621794130"
        },
        {
            "participationCoeff" : 0.5,
            "tweetID" : "6271782334664128453"
        }
    ]
}

基本上,集合具有集群,其中集群具有_id 字段和members 字段。成员字段是一个文档数组,具有以下格式。

{
            "participationCoeff" : 1,
            "tweetID" : "5327010328645530500"
        }

现在,有时我必须通过匹配 tweetID 来删除集群文档的 members 属性中的这些子文档。

但是,我无法找到实现此效果的查询。基本上,一个 tweetID 将参与许多集群,因此将出现在各个集群的“成员”属性的多个子文档中。我想提供一个批量 $pull 操作,我可以在其中删除与特定 tweetID 匹配的所有集群(即它们的成员属性)中的所有子文档。

一些帮助和直觉会很有帮助。

【问题讨论】:

    标签: mongodb pull


    【解决方案1】:

    注意:用于"mongoose": "^5.12.13"

    至于今天 2021 年 6 月 22 日,您可以使用 $in$pull mongodb 运算符从文档数组中删除项目:

    父文档:

    {
        "name": "June Grocery",
        "description": "Remember to pick Ephraim's favorit milk",
        "createdDate": "2021-06-09T20:17:29.029Z",
        "_id": "60c5f64f0041190ad312b419",
        "items": [],
        "budget": 1500,
        "owner": "60a97ea7c4d629866c1d99d1",
    }
    

    Items 数组中的文档:

    {
        "category": "Fruits",
        "bought": false,
        "id": "60ada26be8bdbf195887acc1",
        "name": "Kiwi",
        "price": 0,
        "quantity": 1
    },
    {
        "category": "Toiletry",
        "bought": false,
        "id": "60b92dd67ae0934c8dfce126",
        "name": "Toilet Paper",
        "price": 0,
        "quantity": 1
    },
    {
        "category": "Toiletry",
        "bought": false,
        "id": "60b92fe97ae0934c8dfce127",
        "name": "Toothpaste",
        "price": 0,
        "quantity": 1
    },
    {
        "category": "Toiletry",
        "bought": false,
        "id": "60b92ffb7ae0934c8dfce128",
        "name": "Mouthwash",
        "price": 0,
        "quantity": 1
    },
    {
        "category": "Toiletry",
        "bought": false,
        "id": "60b931fa7ae0934c8dfce12d",
        "name": "Body Soap",
        "price": 0,
        "quantity": 1
    },
    {
        "category": "Fruit",
        "bought": false,
        "id": "60b9300c7ae0934c8dfce129",
        "name": "Banana",
        "price": 0,
        "quantity": 1
    },
    {
        "category": "Vegetable",
        "bought": false,
        "id": "60b930347ae0934c8dfce12a",
        "name": "Sombe",
        "price": 0,
        "quantity": 1
    },
    

    查询:

    MyModel.updateMany(
        { _id: yourDocumentId },
        { $pull: { items: { id: { $in: itemIds } } } },
        { multi: true }
    );
    

    注意:ItemIds 是ObjectId 的数组。 见下文:

    [
      '60ada26be8bdbf195887acc1',
      '60b930347ae0934c8dfce12a',
      '60b9300c7ae0934c8dfce129'
    ] 
    

    【讨论】:

      【解决方案2】:

      与此同时,更新方法已被弃用。因此,一种可能的最新解决方案是改用 u​​pdateMany 方法。

      db.clusters.updateMany({}, 
          {$pull: {members: {tweetID: '5327010328645530500'}}})
      

      【讨论】:

        【解决方案3】:

        这将在单个查询中删除multiple tweets,只需将数组传递给$in:-

        db.clusters.update({}, 
        {$pull: {members: {$in: [ {tweetID: '5327010328645530500'},{"tweetID" : "2820402625046999289"} ] } } }, 
        {multi: true});
        

        上述方法在猫鼬中不起作用 所以对于猫鼬来说:-

         db.clusters.update({}, 
        {$pull: {members:[ {tweetID: '5327010328645530500'},{"tweetID" : "2820402625046999289"} ]  } });
        

        【讨论】:

          【解决方案4】:

          这正是 $pull 运算符所做的,因此在 shell 中您可以使用 update ,例如:

          db.clusters.update({}, 
              {$pull: {members: {tweetID: '5327010328645530500'}}}, 
              {multi: true})
          

          设置multi 选项,以便更新每个文档,而不仅仅是第一个。

          【讨论】:

          • 出现以下错误。 Cannot apply $pull/$pullAll modifier to non-array
          • @VaidAbhishek 这意味着集合中有一些文档,其中 members 不是数组。
          • 我认为我的收藏并非如此。成员将是集群的严格数组类型属性。有没有办法使用聚合来做到这一点!
          • @VaidAbhishek 你确定吗?即使 members 在文档中是 null 也会导致此错误,因为这不是数组。
          • 我不这么认为 :-(
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-03-03
          • 2022-01-08
          • 2013-07-23
          • 2021-11-18
          • 1970-01-01
          相关资源
          最近更新 更多