我有一个类似于以下内容的文档结构:
{
"_id" : "777",
"someKey" : "someValue",
"someArray" : [
{
"name" : "name1",
"someNestedArray" : [
{
"name" : "value"
},
{
"name" : "delete me"
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
我想删除带有"删除我"值的嵌套数组元素.
我知道我可以使用嵌套的$ elemMatch表达式找到与此描述匹配的文档.删除相关元素的查询语法是什么?
Gat*_* VP 44
要删除有问题的项目,您实际上将使用更新.更具体地说,您将使用该$pull
命令进行更新,该命令将从数组中删除该项.
db.temp.update(
{ _id : "777" },
{$pull : {"someArray.0.someNestedArray" : {"name":"delete me"}}}
)
Run Code Online (Sandbox Code Playgroud)
这里发生了一些"魔术".使用.0
表示我们知道我们正在修改第0项someArray
.使用{"name":"delete me"}
表示我们知道我们计划删除的确切数据.
如果将数据加载到客户端然后执行更新,则此过程可以正常工作.如果要执行执行这些操作的"通用"查询,则此过程的效果较差.
我认为最简单的方法就是简单地认识到更新子文档数组通常需要在某些时候将内容保存在内存中.
在回复下面的第一条评论时,您可以通过稍微更改数据结构来帮助您的情况
"someObjects" : {
"name1": {
"someNestedArray" : [
{
"name" : "value"
},
{
"name" : "delete me"
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
现在你可以做到 {$pull : { "someObjects.name1.someNestedArray" : ...
这是你的结构的问题.MongoDB对操纵"子阵列"没有很好的支持.您的结构具有一个对象数组,这些对象包含更多对象的数组.
如果您有以下结构,那么您将很难使用以下内容$pull
:
array [
{ subarray : array [] },
{ subarray : array [] },
]
Run Code Online (Sandbox Code Playgroud)
如果您的结构看起来像那样,并且您想要更新subarray
,则有两个选项:
$pull
.$pull
.将整个对象加载到客户端并使用findAndModify
.Cuo*_*goc 24
MongoDB 3.6 添加了$[]运算符,便于更新包含嵌入文档的数组。所以问题可以通过以下方式解决:
db.test.update(
{ _id : "777" },
{$pull : {"someArray.$[].someNestedArray" : {"name":"delete me"}}}
)
Run Code Online (Sandbox Code Playgroud)
正如@Melkor所说(可能本身就是答案),
如果您不知道索引,请使用:
{_id: TheMainID, "theArray._id": TheArrayID}, {$pull:
{"theArray.$.theNestedArray": {_id: theNestedArrayID}}}
Run Code Online (Sandbox Code Playgroud)
从 MongoDB 3.6 开始,您可以使用它arrayFilters
来执行此操作:
db.test.update(
{ _id: "777" },
{ $pull: { "someArray.$[elem].someNestedArray": { name: "delete me" } } },
{ arrayFilters: [{ "elem.name": "name1"}] }
)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
22744 次 |
最近记录: |