如何从MongoDB文档中的双重嵌套数组中删除元素

我有一个文件结构的东西沿着以下几点:

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

我想删除值为“删除我”的嵌套数组元素。

我知道我可以使用嵌套的$ elemMatchexpression式find符合这个描述的文档。 删除相关元素的查询语法是什么?

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

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

这里发生了一些“魔术”。 使用.0表示我们知道我们正在修改someArray的第0项。 使用{"name":"delete me"}表示我们知道我们打算删除的确切数据。

如果您将数据加载到客户端,然后执行更新,则此过程可以正常工作。 如果要执行执行这些操作的“通用”查询,则此过程不太好。

我认为简单地认识到更新子文档数组通常要求您在某个时刻拥有原始的内存。


为了回应下面的第一条评论,你可以通过稍微改变数据结构来帮助你的情况

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

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

这是你的结构的问题。 MongoDB对操作“子数组”没有很好的支持。 你的结构有一个对象数组,这些对象包含更多对象的数组。

如果你有以下结构,你将会遇到困难的时候,比如$pull

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

如果你的结构看起来像这样你想更新subarray你有两个select:

  1. 改变你的结构,以便你可以利用$pull
  2. 不要使用$pull 。 将整个对象加载到客户端并使用findAndModify

正如@Melkor所评论的(应该可能是自己的答案),

如果你不知道索引使用:

 {_id: TheMainID, theArray._id: TheArrayID}, {$pull: {"theArray.$.theNestedArray": {_id: theNestedArrayID}}}