尝试更新Mongo中子文档数组中的元素时遇到问题。如果我在集合" resource"
中考虑以下文档{
"_id": 1,
"resources": [
{
"resource_id": 1,
"resource_list": ["item1","item2"]
},
{
"resource_id": 2,
"resource_list": ["item4","item3"]
}
]
}
我想更新"item4"
以及"item5"
"resource_id" = 2
以下语句给出了一个错误:如果没有包含数组的相应查询字段,则无法应用位置运算符。
db.resource.update({"resources.resource_id": 2, "resources.resource_list": "item4"}, {$set: {"resources.$.resource_list.$": "item5"}})
对此的任何帮助都将受到高度赞赏。
答案 0 :(得分:1)
位置运算符只能在查询中使用一次。这是一个限制,有一个开放的改进票:https://jira.mongodb.org/browse/SERVER-831
解决这个问题的另一种方法可能是推动" item5"到数组并拉出" item4"。像这样:
db.resource.update({ "resources.resource_id": 2, "resources.resource_list": "item4" }, { $pull: { "resources.$.resource_list": "item4" }, $push: { "resources.$.resource_list": "item5" } })
然而,这是不可能的,$pull
和$push
不能用于同一字段的同一查询中。相关票证:https://jira.mongodb.org/browse/SERVER-1050
我看到两个解决方案。一种是执行两个查询。在第一个查询中,您在第二个查询中按" item5"," item4":
db.resource.update({ "resources.resource_id": 2, "resources.resource_list": "item4" }, { $push: { "resources.$.resource_list": "item5" } });
db.resource.update({ "resources.resource_id": 2, "resources.resource_list": "item4" }, { $pull: { "resources.$.resource_list": "item4" } });
如果要在一个查询中执行此操作,可以使用mongo shell。像这样:
db.resource.find({ 'resources.resource_id': 2, 'resources.resource_list': 'item4' }).forEach( function(document) {
for (var i in document.resources) {
if (document.resources[i].resource_id == 2) {
var index = document.resources[i].resource_list.indexOf('item4');
document.resources[i].resource_list[index] = 'item5';
db.resource.save(document);
}
}
})
答案 1 :(得分:0)
符号$
仅修改搜索中最后一个数组的最后位置,您可以使用$addToSet
或$push
添加项目...
> db.resource.find()
{ "_id" : 1,
"resources" : [
{ "resource_id" : 1,
"resource_list" : [ "item1","item2" ] },
{ "resource_id" : 2,
"resource_list" : [ "item4", "item3" ] } ] }
> db.resource.update({"resources.resource_id": 2,
"resources.resource_list": "item4"},
{$addToSet:{"resources.$.resource_list": "item5"}})
> db.resource.find()
{ "_id" : 1, "resources" : [
{ "resource_id" : 1,
"resource_list" : [ "item1", "item2" ] },
{ "resource_id" : 2,
"resource_list" : [ "item4", "item3", "item5" ] } ] }
> db.resource.update({"resources.resource_id": 2,
"resources.resource_list": "item4"},
{$pull: {"resources.$.resource_list": "item4"}})
> db.resource.find()
{ "_id" : 1, "resources" : [
{ "resource_id" : 1,
"resource_list" : [ "item1", "item2" ] },
{ "resource_id" : 2,
"resource_list" : [ "item3","item5" ] } ] }
但最好同时运行两个查询?
> db.algo.update({"resources.resource_id": 2,
"resources.resource_list": "item4"},
{$addToSet:{"resources.$.resource_list": "item5"},
$pull: {"resources.$.resource_list": "item4"}})
修饰符不允许使用字段名重复