微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用 $pull 在 mongodb 中删除数组内的文档

如何解决如何使用 $pull 在 mongodb 中删除数组内的文档

我有以下文档结构

{
    "_id" : ObjectId("5ffef283f1f06ff8524aa2c2"),"applicationName" : "TestApp","pName" : "","environments" : [],"stages" : [],"createdAt" : ISODate("2021-01-15T09:51:35.546Z"),"workflows" : [ 
        [ 
            {
                "pName" : "Test1","wName" : "TestApp_Test1","agent" : ""
            },{
                "pName" : "Test2","wName" : "TestApp_Test2","agent" : ""
            }
        ],[ 
            {
                "pName" : "Test1","agent" : ""
            }
        ]
    ],"updatedAt" : Date(-62135596800000)
}

我希望删除出现的

{
        "pName" : "Test1","agent" : ""
}

所以,生成的文档应该是这样的

{
        "_id" : ObjectId("5ffef283f1f06ff8524aa2c2"),"workflows" : [ 
            [ 
                {
                    "pName" : "Test2","agent" : ""
                }
            ]
        ],"updatedAt" : Date(-62135596800000)
    }

我已经尝试过下面的 mongo 查询

db.getCollection('workflows').update({_id:ObjectId('5ffef283f1f06ff8524aa2c2')},{$pull:{workflows: { $elemmatch: {pipelineName: 'Test1'}}}} )

这是从工作流字段中删除所有文档,包括 Test2,因为 Test1 匹配。

我们如何只删除 Test1 的条目并保留其他条目?

解决方法

您可以使用位置运算符“$[]”来实现:

db.getCollection('workflows').update({_id: ObjectId("5ffef283f1f06ff8524aa2c2")  },{$pull: {"workflows.$[]":{pName:"Test1"  } }  } )

但架构看起来有点奇怪,更新后,如果子数组中的所有元素都被删除,工作流中将出现空数组。 要修复空子数组,您需要执行第二个操作来删除它们:

db.getCollection('workflows').update({_id: ObjectId("5ffef283f1f06ff8524aa2c2")  },{$pull: {"workflows":[]  } }   )
,

您不能使用 $elemMatch,因为它返回数组中的第一个匹配元素。

我不确定使用提供的架构设计是否还有另一种最佳方法。

play

db.collection.aggregate({
  "$unwind": "$workflows"
},{
  "$unwind": "$workflows"
},{
  "$match": {
    "workflows.pName": {
      "$ne": "Test1"
    }
  }
},{
  "$group": {
    "_id": "$_id",workflows: {
      $push: "$workflows"
    },applicationName: {
      "$first": "$applicationName"
    }
  }
},applicationName: {
      "$first": "$applicationName"
    }
  }
})
  1. unwind 需要两次对数据进行反规范化
  2. match 过滤掉不必要的文档
  3. group 需要两次才能带来所需的输出

您可以使用 $out 作为最后阶段将其保存到集合中。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?