我有一个文档 struct ,大致如下:

{
"_id" : "777",
"someKey" : "someValue",
"someArray" : [
    {
        "name" : "name1",
        "someNestedArray" : [
            {
                "name" : "value"
            },
            {
                "name" : "delete me"
            }
        ]
    }
  ]
}

我想删除值为"delete me"的嵌套数组元素.

我知道我可以使用嵌套的$elemMatch表达式找到与此描述匹配的文档.删除相关元素的查询语法是什么?

推荐答案

要删除有问题的项目,实际上需要使用更新.更具体地说,您将使用$pull命令进行更新,该命令将从数组中删除该项.

db.temp.update(
  { _id : "777" },
  {$pull : {"someArray.0.someNestedArray" : {"name":"delete me"}}}
)

这里发生了一点"魔法".使用.0表示我们知道我们正在修改someArray的第0项.使用{"name":"delete me"}表示我们知道计划删除的确切数据.

如果将数据加载到客户机中,然后执行更新,这个过程就可以正常工作.如果要执行执行这些操作的"通用"查询,则此过程的效果较差.

我认为最简单的方法是简单地认识到,更新子文档数组通常需要在某个时刻将原始文档存储在内存中.


作为对下面第一条 comments 的回应,您可能可以通过稍微更改数据 struct 来帮助您的情况

"someObjects" : {
  "name1":  {
        "someNestedArray" : [
            {
                "name" : "value"
            },
            {
                "name" : "delete me"
            }
        ]
    }
}

现在你可以做{$pull : { "someObjects.name1.someNestedArray" : ...

你的 struct 有问题.MongoDB对操作"子数组"没有很好的支持.您的 struct 有一个对象数组,这些对象包含更多对象的array.

如果你有以下 struct ,你将很难使用$pull这样的东西:

array [
  { subarray : array [] },
  { subarray : array [] },
]

如果你的 struct 看起来像and,你想更新subarray,你有两个 Select :

  1. 改变你的 struct ,这样你就可以利用$pull.
  2. 不要用$pull.将整个对象加载到客户端并使用findAndModify.

Mongodb相关问答推荐

当日期和时间在不同键的字符串中时,Mongo 查询过滤今天的数据

MongoDB 在一个聚合中包含多个组

如何在MongoDB中搜索有序子集的方法?

在延迟函数中重用 context.WithTimeout

MongoDB - 家庭作业(job)帮助.不确定如何在 mongodb 中访问文档中的变量

如何在 MongoDB 中已经存在的 slug 中添加一个随机数?

如何将以下聚合查询转换为 bson 并在 golang 中执行

Mongo:投影不影响布尔值

如何在mongoDB中按嵌套文档分组( group by )

MongoDB 支持的最 Big Data 库数

Raft Vs MongoDB 初选

使用 EventSourcing(NodeJS、MongoDB、JSON)跨多个偶尔连接的客户端同步数据

获取收集字节使用情况统计信息的pymongo方法?

从 MongoDB find() 结果集中识别最后一个文档

在 MongoDB 中创建简短、唯一的对象 ID

嵌套数组内的Mongodb增量值

Mongoose.js 通过一个 connect() 调用创建到 MongoDB 的多个连接

带有 jQ​​uery Ajax/JSON 前端的 MongoDB 或 CouchDB 中间件

MongoDB聚合将字符串数组连接到单个字符串

查询 Mongoid/rails 3 中的嵌入对象(Lower than、Min 运算符和排序)