如何在 mongo 上删除嵌套数组中的项目
how to remove item in nested array on mongo
我需要删除嵌套数组中的项目,以下是我的文档
{
"_id" : ObjectId("58760d8caa30c585ef8d3beb"),
"results" : [
{
"item" : "A",
"score" : 5.0,
"answers" : [
{
"q" : 1.0,
"a" : 4.0
},
{
"q" : 1.0,
"a" : 5.0
},
{
"q" : 2.0,
"a" : 6.0
}
]
},
{
"item" : "B",
"score" : 8.0,
"answers" : [
{
"q" : 1.0,
"a" : 7.0
},
{
"q" : 1.0,
"a" : 5.0
},
{
"q" : 2.0,
"a" : 9.0
}
]
}
]
}
我想删除答案中所有 q 等于 1.0 的项目,以下是预期文档:
{
"_id" : ObjectId("58760d8caa30c585ef8d3beb"),
"results" : [
{
"item" : "A",
"score" : 5.0,
"answers" : [
{
"q" : 2.0,
"a" : 6.0
}
]
},
{
"item" : "B",
"score" : 8.0,
"answers" : [
{
"q" : 2.0,
"a" : 9.0
}
]
}
]
}
我用过:
db.getCollection('test').update({"results.answers.q":1},
{ $pull: {"results.$.answers": {q:1} } },
{ multi: true })
但是得到了:
{
"_id" : ObjectId("58760d8caa30c585ef8d3beb"),
"results" : [
{
"item" : "A",
"score" : 5.0,
"answers" : [
{
"q" : 2.0,
"a" : 6.0
}
]
},
{
"item" : "B",
"score" : 8.0,
"answers" : [
{
"q" : 1.0,
"a" : 7.0
},
{
"q" : 1.0,
"a" : 5.0
},
{
"q" : 2.0,
"a" : 9.0
}
]
}
]
}
在项目 B 中还有 q 等于 1 的嵌入文档
我该怎么办?
不幸的是,没有办法通过单个查询获得这个结果,除非有人能用 $where
运算符想出一些非常聪明的东西。使用位置运算符意味着您只能定位单个数组元素(在您的情况下它是单个 results
元素),并且这种用法在任何子数组拉动中都是必须的。
此处一个丑陋的解决方法是执行此更新 N 次,其中 N 是 results
数组的长度。这种方法可以完成这项工作,但显然如果这些数组很大,这将是一个巨大的性能问题。
使用以下查询即可。有关 $pull 的更多信息,请访问 https://docs.mongodb.com/manual/reference/operator/update/pull/
db.getCollection('test').update({},{ $pull: {"results":{"answers": {$elemMatch:{q:1} }} }},{ multi: true });
您现在可以根据 MongoDB 文档使用 $pull 实现此目的:https://docs.mongodb.com/manual/reference/operator/update/pull/#pull-array-of-documents
我需要删除嵌套数组中的项目,以下是我的文档
{
"_id" : ObjectId("58760d8caa30c585ef8d3beb"),
"results" : [
{
"item" : "A",
"score" : 5.0,
"answers" : [
{
"q" : 1.0,
"a" : 4.0
},
{
"q" : 1.0,
"a" : 5.0
},
{
"q" : 2.0,
"a" : 6.0
}
]
},
{
"item" : "B",
"score" : 8.0,
"answers" : [
{
"q" : 1.0,
"a" : 7.0
},
{
"q" : 1.0,
"a" : 5.0
},
{
"q" : 2.0,
"a" : 9.0
}
]
}
]
}
我想删除答案中所有 q 等于 1.0 的项目,以下是预期文档:
{
"_id" : ObjectId("58760d8caa30c585ef8d3beb"),
"results" : [
{
"item" : "A",
"score" : 5.0,
"answers" : [
{
"q" : 2.0,
"a" : 6.0
}
]
},
{
"item" : "B",
"score" : 8.0,
"answers" : [
{
"q" : 2.0,
"a" : 9.0
}
]
}
]
}
我用过:
db.getCollection('test').update({"results.answers.q":1},
{ $pull: {"results.$.answers": {q:1} } },
{ multi: true })
但是得到了:
{
"_id" : ObjectId("58760d8caa30c585ef8d3beb"),
"results" : [
{
"item" : "A",
"score" : 5.0,
"answers" : [
{
"q" : 2.0,
"a" : 6.0
}
]
},
{
"item" : "B",
"score" : 8.0,
"answers" : [
{
"q" : 1.0,
"a" : 7.0
},
{
"q" : 1.0,
"a" : 5.0
},
{
"q" : 2.0,
"a" : 9.0
}
]
}
]
}
在项目 B 中还有 q 等于 1 的嵌入文档
我该怎么办?
不幸的是,没有办法通过单个查询获得这个结果,除非有人能用 $where
运算符想出一些非常聪明的东西。使用位置运算符意味着您只能定位单个数组元素(在您的情况下它是单个 results
元素),并且这种用法在任何子数组拉动中都是必须的。
此处一个丑陋的解决方法是执行此更新 N 次,其中 N 是 results
数组的长度。这种方法可以完成这项工作,但显然如果这些数组很大,这将是一个巨大的性能问题。
使用以下查询即可。有关 $pull 的更多信息,请访问 https://docs.mongodb.com/manual/reference/operator/update/pull/
db.getCollection('test').update({},{ $pull: {"results":{"answers": {$elemMatch:{q:1} }} }},{ multi: true });
您现在可以根据 MongoDB 文档使用 $pull 实现此目的:https://docs.mongodb.com/manual/reference/operator/update/pull/#pull-array-of-documents