我正在寻找最有效的方法来从此结构修改集合的所有文档:
{
[...]
myValues:
{
a: "any",
b: "content",
c: "can be found here"
}
[...]
}
所以变成这样:
{
[...]
a: "any",
b: "content",
c: "can be found here"
[...]
}
基本上,我希望将myValues
字段下的所有内容都放入集合的所有文档的父文档中。
我一直在寻找一种使用dbCollection.updateMany()
在单个查询中执行此操作的方法,除非似乎myValues
的内容对于所有文档都相同,否则似乎不可能做到这一点。 。但是在我的情况下,myValues
的内容从一个文档更改为另一个文档。例如,我尝试过:
db.getCollection('myCollection').updateMany({ myValues: { $exists: true } }, { $set: '$myValues' });
认为它可能会解决myValues
对象,并使用该对象在文档中进行设置。但是它返回一个错误,指出将字符串分配给$set
字段是非法的。
那么,对于我想做的事情,最有效的方法是什么?是否可以通过一个命令来更新集合中的所有文档?
还是我需要遍历集合的每个文档,并逐个更新它们?
目前,我使用以下代码遍历所有文档:
var documents = await myCollection.find({ myValues: { $exists: true } });
for (var document = await documents.next(); document != null; document = await documents.next())
{
await myCollection.updateOne({ _id: document._id }, { $set: document.myValues, $unset: { myValues: 1} });
}
由于我的收藏很大,因此执行起来会花费很长时间。
答案 0 :(得分:1)
您可以考虑使用$out作为替代的单命令解决方案。它可用于将现有集合替换为聚合的输出。知道您可以编写以下聚合管道:
db.myCollection.aggregate([
{
$replaceRoot: {
newRoot: {
$mergeObjects: [ "$$ROOT", "$myValues" ]
}
}
},
{
$project: {
myValues: 0
}
},
{
$out: "myCollection"
}
])
$replaceRoot使您可以升级将旧的$$ROOT
和myValues
合并到根级别的对象。