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

时间:2011-03-08 04:05:39

标签: mongodb

我的文档结构类似于以下内容:

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

我想删除嵌套数组元素,其值为“delete me”。

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

5 个答案:

答案 0 :(得分:41)

要删除相关项目,您实际上将使用更新。更具体地说,您将使用$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,你有两个选择:

  1. 更改您的结构,以便您可以利用$pull
  2. 请勿使用$pull。将整个对象加载到客户端并使用findAndModify

答案 1 :(得分:5)

正如@Melkor所评论的那样(应该可能就是答案),

如果您不知道索引使用:

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

答案 2 :(得分:2)

MongoDB 3.6添加了$[]运算符,该运算符有助于更新包含嵌入式文档的数组。因此可以通过以下方法解决问题:

db.test.update(
  { _id : "777" },
  {$pull : {"someArray.$[].someNestedArray" : {"name":"delete me"}}}
)

答案 3 :(得分:1)

从MongoDB 3.6开始,您可以使用arrayFilters执行此操作:

db.test.update(
  { _id: "777" }, 
  { $pull: { "someArray.$[elem].someNestedArray": { name: "delete me" } } },
  { arrayFilters: [{ "elem.name": "name1"}] }
)

另请参阅https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/index.html#update-all-documents-that-match-arrayfilters-in-an-array

答案 4 :(得分:0)

其他示例和用法如下:

{

    "company": {
        "location": {
            "postalCode": "12345",
            "Address": "Address1",
            "city": "Frankfurt",
            "state": "Hessen",
            "country": "Germany"
        },
        "establishmentDate": "2019-04-29T14:12:37.206Z",
        "companyId": "1",
        "ceo": "XYZ"
    },
    "items": [{
            "name": "itemA",
            "unit": "kg",
            "price": "10"
        },
        {
            "name": "itemB",
            "unit": "ltr",
            "price": "20"
        }

    ]
}
  1. 删除:Mongodb查询以删除ItemB:
db.getCollection('test').update(   
    {"company.companyId":"1","company.location.city":"Frankfurt"},
    {$pull : {"items" : {"name":"itemB"}}}
)
  1. 查找:查找有关itemB的查询:
db.getCollection('test').find(
    {"company.companyId":"1","company.location.city":"Frankfurt","items.name":"itemB"},
    { "items.$": 1 }
)

3.UPDATE:更新itemB的查询:

db.getCollection('test').update
(
 {"company.companyId":"1","company.location.city":"Frankfurt","items.name":"itemB"},
 { $set: { "items.$[].price" : 90 }}, 
   { multi: true });