MongoDB 更新插入 $in
Posted
技术标签:
【中文标题】MongoDB 更新插入 $in【英文标题】:MongoDB upsert $in 【发布时间】:2021-10-26 15:20:16 【问题描述】:我有一堆记录要更新插入特定的产品 ID。根据之前的计算,我想记录该产品在当前周/年的类型。
问题是我想不出一种方法来做到这一点,除了一次一个。现在我在做:
a_group.forEach(p =>
db.abc.update(
product_id: p._id,
year: 2021
,
$set:
'abc.34': 'a'
,
upsert: true
);
);
a_group
只是一系列产品。
如果产品阵列很大,这确实很重。它只是执行a_group.length
upsert 操作。
理想情况下,我想做这样的事情:
db.abc.update(
product_id: $in: a_group.map(p => p._id) ,
year: 2021
,
$set:
'abc.34': 'a'
,
upsert: true,
multi: true
);
这将看到 a_group 是一个数组,并尝试匹配并更新数组中的每个项目。除非那行不通。
非常感谢任何帮助。
【问题讨论】:
您是直接在 mongodb shell 中、通过 mongodb js 驱动程序还是从 Meteor(在集合上)执行此操作? @ChristianFritz 我明白你为什么这么问。试图简化代码的另一个错误。在 Meteor 中将是ABC.update()
。我在 Meteor 中做ABC.rawCollection()
使用@Joe 的解决方案。
【参考方案1】:
这里的问题是您需要为 _id 的每个离散值单独更新插入。
来自文档:
一个更新:
更新与您的查询过滤器匹配的文档 如果没有与您的查询过滤器匹配的文档,则插入文档
在 upsert 的情况下,例如:
updateMany(
a:$in[1,2,3],
$set:b:true,
upsert: true
)
如果存在包含a: 3
的文档,那么它将匹配查询过滤器,因此将更新一个文档,并且不会发生插入。
如果没有文档与传递给$in
的任何值匹配,则将插入一个单个新文档。由于查询无法确定您想要的a
的值,因此它将创建一个包含b:true
的文档,但将留下a
未定义。
您可能想要的是一个批量操作,它可以通过一次调用数据库来执行许多 upsert 操作。
使用 mongosh shell,可能看起来像:
let ops = [];
a_group.forEach(p =>
ops.push(
updateOne:
filter:
product_id: p._id,
year: 2021
,
update: $set: 'abc.34': 'a',
upsert: true
);
);
db.abc.bulkWrite(ops)
查看您正在使用的驱动程序的文档,了解如何进行批量操作。
【讨论】:
【参考方案2】:根据您的代码,我认为 a_group
是对象数组,因为您在 forEach 中使用 p._id ,
您应该从a_group
导出_id 并推入新数组,例如productsId
并替换
product_id: $in: a_group
与
product_id: $in: productsId ,
【讨论】:
对不起,我的实际代码就是这种情况。我尝试简化示例,以便更容易讨论实际问题,但似乎略有疏忽。我已经更正了示例代码。以上是关于MongoDB 更新插入 $in的主要内容,如果未能解决你的问题,请参考以下文章
???????????????????????? - ???????(IN MONGODB)
解析服务器在 mongodb 中创建相同的 objectid