【问题标题】:MongoDB: Delete documents from array in multiple documentsMongoDB:从多个文档中的数组中删除文档
【发布时间】:2021-11-18 03:15:18
【问题描述】:

我还在了解 MongoDB 和 NoSql 数据库,我正在尝试更新一个集合。

在我的收藏中,我有多个如下所示的文档:

{
    "name": "store1",
    "products": [
        {
            "name": "product 1",
            "reviews": [
                {
                    "user": "john doe",
                    "stars": 5,
                },
                {
                    "user": "jane doe",
                    "stars": 1,
                }
            ]
        },
        {
            "name": "product 2",
            "reviews": [
                {
                    "user": "jane doe",
                    "stars": 3,
                }
            ]
        }
    ]
}

每个文档都有一个文档数组“products”,该数组中的每个文档都有一个文档数组“reviews”

对于集合中的每个文档,我想从“产品”中删除至少有 1 星评论的文档 = "stars": 1

因此,对于上面的示例,更新后的文档将如下所示


{
    "name": "store1",
    "products": [
        {
            "name": "product 2",
            "reviews": [
                {
                    "user": "jane doe",
                    "stars": 3,
                }
            ]
        }
    ]
}

【问题讨论】:

    标签: database mongodb nosql


    【解决方案1】:

    您可以使用$pull 运算符来删除数组中的对象。

    db.collection.update({
      "products.reviews.stars": 1
    },
    {
      "$pull": {
        "products": {
          "reviews.stars": 1
        }
      }
    })
    

    例如here

    【讨论】:

    • 谢谢,没想到这么简单。我试图做类似的事情,但我以一种更复杂的方式在做这件事而没有注意到。编辑:我必须使用.updateMany() 才能从多个文档中删除,因为.update() 仅从第一个文档中删除。
    【解决方案2】:

    查询 (聚合流水线方式,需要mongodb 4.2+)

    • 这里不需要聚合管道,但你也可以这样做 ​

    Test code here

    db.collection.update({},
    [
     ​{
       ​"$set": {
         ​"products": {
           ​"$filter": {
             ​"input": "$products",
             ​"cond": {
               ​"$not": [
                 ​{
                   ​"$in": [
                     ​1,
                     ​"$$p.reviews.stars"
                   ​]
                 ​}
               ​]
             ​},
             ​"as": "p"
           ​}
         ​}
       ​}
     ​}
    ])
    

    因为您只有 1-5 星过滤器是空的,否则 "products.reviews.stars": 1,可以使用。 (即使你有星星的索引,它的选择性也会很低,可能会让事情变得更糟)

    【讨论】:

      猜你喜欢
      • 2015-05-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-28
      • 2013-07-23
      • 1970-01-01
      • 2022-11-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多