gpt4 book ai didi

mongodb - 使用 $addToSet 修饰符在前面添加值

转载 作者:可可西里 更新时间:2023-11-01 09:56:48 26 4
gpt4 key购买 nike

我正在尝试在 mongo 上运行更新查询,这将在现有数组属性中添加一些值。

我的目标是在数组的开头添加元素,而不是在默认情况下发生在末尾。这是我正在使用的代码:

db.collection("Project").update({'_id': group.project}, {$addToSet: {'endpointOrder': {$each: group.endpointOrder, $position: 0}}}, {multi: true})

正如您在上面所看到的,如果我只是将“addToSet”更改为使用“push”修饰符,则可以正常工作,但这将保留重复项,但这是不可能的。所以,我的假设是,$position 仅支持 '$push',不支持 '$addToSet'。

关于如何实现该目标的任何想法/建议?谢谢。

最佳答案

$addToSet运算符生成一组“独特”的项目,这很可能是您所追求的。不幸的是,对于这个和其他“集合运算符”,MongoDB 有一个共同的口头禅:

"Sets are not considered to be ordered"

因此,当您将项目添加到“集合”(或与其他操作组合)时,无法保证项目出现在任何位置,无论是“集合”的开头还是结尾。官方说法是,任何元素都可以以任何顺序出现,只要是“集合”的一部分就无所谓。

但还有另一种解决方法,它只是意味着您不使用 $addToSet 而是结合使用一些其他过滤逻辑和 $push:

考虑文档:

{ "a": [ 3,1,2 ] }

因此,如果我想向列表中添加一个新元素 4 并将其添加到该元素尚未属于“集合”的“第一个”位置,那么您只需构造像这样查询和更新:

db.collection.update(
{ "a": { "$ne": 4 } },
{ "$push": { "a": { "$each": [4], "$position": 0 } } }
)

简而言之:“如果值已经存在于数组中,则不要推送到数组。”

事实上,仅此而已。如果您要求添加一个已经存在的元素,那么查询条件当然会是 false,并且不会修改任何内容。

最后,您将获得与使用 $addToSet 操作相同的结果,除了您可以完全控制元素定位,甚至可以根据需要进行“排序”。您需要做的就是在决定是否更改任何内容之前检查匹配的元素。


处理多个元素的过程实际上应该使用“批量”操作 API 以获得最高效率

var items = [4,3];

var bulk = db.collection.initializeOrderedBulkOp();
bulk.find({ "a": { "$nin": items } }).updateOne(
{ "$push": { "a": { "$each": items, "$position": 0 } } }
);

items.forEach(function(item) {
bulk.find({ "a": { "$ne": item } }).updateOne(
{ "$push": { "a": { "$each": [item], "$position": 0 } } }
);
});
bulk.execute();

这将导致循环中只有一个更新操作实际匹配或修改任何内容:

{ "a": [ 4,3,1,2 ] }

或者使用根本不存在的值:

var items = [5,8];

var bulk = db.collection.initializeOrderedBulkOp();
bulk.find({ "a": { "$nin": items } }).updateOne(
{ "$push": { "a": { "$each": items, "$position": 0 } } }
);

items.forEach(function(item) {
bulk.find({ "a": { "$ne": item } }).updateOne(
{ "$push": { "a": { "$each": [item], "$position": 0 } } }
);
});
bulk.execute();

然后第一个操作实际上会修改并且循环指令将不会匹配任何内容,因为项目已经存在。

{ "a": [ 5,8,4,3,1,2 ] }

关于mongodb - 使用 $addToSet 修饰符在前面添加值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31276884/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com