如何从 MongoDB 文档中的双重嵌套数组中删除元素。
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5228210/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to remove an element from a doubly-nested array in a MongoDB document.
提问by rshepherd
I have a document structure something along the lines of the following:
我有一个类似以下内容的文档结构:
{
"_id" : "777",
"someKey" : "someValue",
"someArray" : [
{
"name" : "name1",
"someNestedArray" : [
{
"name" : "value"
},
{
"name" : "delete me"
}
]
}
]
}
I want to delete the nested array element with the value "delete me".
我想删除值为“删除我”的嵌套数组元素。
I know I can find documents which match this description using nested $elemMatch expressions. What is the query syntax for removing the element in question?
我知道我可以使用嵌套的 $elemMatch 表达式找到与此描述匹配的文档。删除相关元素的查询语法是什么?
回答by Gates VP
To delete the item in question you're actually going to use an update. More specifically you're going to do an update with the $pull
command which will remove the item from the array.
要删除有问题的项目,您实际上将使用更新。更具体地说,您将使用$pull
将从数组中删除项目的命令进行更新。
db.temp.update(
{ _id : "777" },
{$pull : {"someArray.0.someNestedArray" : {"name":"delete me"}}}
)
There's a little bit of "magic" happening here. Using .0
indicates that we know that we are modifying the 0th item of someArray
. Using {"name":"delete me"}
indicates that we know the exact data that we plan to remove.
这里发生了一些“魔法”。Using.0
表示我们知道我们正在修改 的第 0 项someArray
。Using{"name":"delete me"}
表示我们知道我们计划删除的确切数据。
This process works just fine if you load the data into a client and then perform the update. This process works less well if you want to do "generic" queries that perform these operations.
如果您将数据加载到客户端然后执行更新,则此过程会正常工作。如果您想执行执行这些操作的“通用”查询,则此过程的效果较差。
I think it's easiest to simply recognize that updating arrays of sub-documents generally requires that you have the original in memory at some point.
我认为最简单的方法是简单地认识到更新子文档数组通常需要您在某个时候将原始文档保存在内存中。
In response to the first comment below, you can probably help your situation by changing the data structure a little
针对下面的第一条评论,您可能可以通过稍微更改数据结构来帮助您的情况
"someObjects" : {
"name1": {
"someNestedArray" : [
{
"name" : "value"
},
{
"name" : "delete me"
}
]
}
}
Now you can do {$pull : { "someObjects.name1.someNestedArray" : ...
现在你可以做 {$pull : { "someObjects.name1.someNestedArray" : ...
Here's the problem with your structure. MongoDB does not have very good support for manipulating "sub-arrays". Your structure has an array of objects and those objects contain arrays of more objects.
这是你的结构问题。MongoDB 对操作“子数组”没有很好的支持。你的结构有一个对象数组,这些对象包含更多对象的数组。
If you have the following structure, you are going to have a difficult time using things like $pull
:
如果您有以下结构,您将很难使用以下内容$pull
:
array [
{ subarray : array [] },
{ subarray : array [] },
]
If your structure looks like that andyou want to update subarray
you have two options:
如果您的结构看起来像这样并且您想要更新,subarray
您有两个选择:
- Change your structure so that you can leverage
$pull
. - Don't use
$pull
. Load the entire object into a client and usefindAndModify
.
- 更改您的结构,以便您可以利用
$pull
. - 不要使用
$pull
. 将整个对象加载到客户端并使用findAndModify
.
回答by Aryeh Armon
As @Melkor has commented (should probably be an answer as itself),
正如@Melkor 所评论的那样(本身应该是一个答案),
If you do not know the index use:
如果您不知道索引,请使用:
{_id: TheMainID, "theArray._id": TheArrayID}, {$pull:
{"theArray.$.theNestedArray": {_id: theNestedArrayID}}}
回答by Cuong Le Ngoc
回答by rafiquenazir
Other example and usage could be like this:
其他示例和用法可能是这样的:
{
"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"
}
]
}
- DELETE : Mongodb Query to delete ItemB:
- DELETE : Mongodb 查询删除 ItemB:
db.getCollection('test').update(
{"company.companyId":"1","company.location.city":"Frankfurt"},
{$pull : {"items" : {"name":"itemB"}}}
)
- FIND: Find query for itemB:
- FIND:查找 itemB 的查询:
db.getCollection('test').find(
{"company.companyId":"1","company.location.city":"Frankfurt","items.name":"itemB"},
{ "items.$": 1 }
)
3.UPDATE : update query for itemB:
3.UPDATE : 更新 itemB 的查询:
db.getCollection('test').update
(
{"company.companyId":"1","company.location.city":"Frankfurt","items.name":"itemB"},
{ $set: { "items.$[].price" : 90 }},
{ multi: true });
回答by Sepp Renfer
From MongoDB 3.6 on you can use arrayFilters
to do this:
从 MongoDB 3.6 开始,您可以使用以下arrayFilters
方法执行此操作:
db.test.update(
{ _id: "777" },
{ $pull: { "someArray.$[elem].someNestedArray": { name: "delete me" } } },
{ arrayFilters: [{ "elem.name": "name1"}] }
)