Sal*_*ali 16 mongodb mongodb-query
我有一个集合,哪些元素可以简化为:
{tags : [1, 5, 8]}
数组中至少有一个元素,所有元素都应该不同.我想用一个标签替换另一个标签,我认为不会有问题.所以我想出了以下查询:
db.colll.update({
tags : 1
},{
$pull: { tags: 1 },
$addToSet: { tags: 2 }
}, {
multi: true
})
Run Code Online (Sandbox Code Playgroud)
很酷,所以它会找到所有带有我不需要的标签的元素(1),删除它并添加另一个(2)如果它不存在.问题是我收到一个错误:
"无法同时更新'标签'和'标签'"
这基本上意味着我不能同时做pull和addtoset.有没有其他方法可以做到这一点?
当然,我可以记住元素的所有ID,然后删除标记并添加单独的查询,但这听起来不太好.
Nei*_*unn 18
错误几乎就是它的意思,因为你不能在同一个更新操作中对同一个"路径"的两个东西起作用.您正在使用的两个运算符不会像您认为的那样按顺序处理.
您可以使用"顺序"执行此操作,因为您可以使用"批量"操作API或其他形式的"批量"更新.在理由当然,也是相反的:
var bulk = db.coll.initializeOrderedBulkOp();
bulk.find({ "tags": 1 }).updateOne({ "$addToSet": { "tags": 2 } });
bulk.find({ "tags": 1 }).updateOne({ "$pull": { "tags": 1 } });
bulk.execute();
Run Code Online (Sandbox Code Playgroud)
不保证没有其他任何东西会尝试修改,但它与您目前所获得的一样接近.
另请参阅包含多个文档的原始"更新"命令.
如果您要同时删除和添加,则可能会对"地图"进行建模,而不是"设置".如果是这样,对象可能比数组少工作.
而不是数据作为数组:
{ _id: 'myobjectwithdata',
data: [{ id: 'data1', important: 'stuff'},
{ id: 'data2', important: 'more'}]
}
Run Code Online (Sandbox Code Playgroud)
使用数据作为对象:
{ _id: 'myobjectwithdata',
data: { data1: { important: 'stuff'},
data2: { important: 'more'} }
}
Run Code Online (Sandbox Code Playgroud)
然后单命令更新:
db.coll.update(
'myobjectwithdata',
{ $set: { 'data.data1': { important: 'treasure' } }
);
Run Code Online (Sandbox Code Playgroud)
从 开始Mongo 4.4,$function聚合运算符允许应用自定义 javascript 函数来实现 MongoDB 查询语言不支持的行为。
再加上对db.collection.update()in 的改进Mongo 4.2,可以接受聚合管道,允许根据自己的值更新字段,
我们可以以语言不允许的方式操作和更新数组:
// { "tags" : [ 1, 5, 8 ] }
db.collection.updateMany(
{ tags: 1 },
[{ $set:
{ "tags":
{ $function: {
body: function(tags) { tags.push(2); return tags.filter(x => x != 1); },
args: ["$tags"],
lang: "js"
}}
}
}]
)
// { "tags" : [ 5, 8, 2 ] }
Run Code Online (Sandbox Code Playgroud)
$function 需要3个参数:
body,这是要应用的函数,其参数是要修改的数组。该功能在这里简单地由在push荷兰国际集团2的阵列和filter荷兰国际集团了1。args,其中包含该body函数作为参数的记录字段。在我们的例子中,"$tag".lang,这body是编写函数的语言。仅js当前可用。| 归档时间: |
|
| 查看次数: |
10926 次 |
| 最近记录: |