我有一个收集点:
- spotId
- name
和代码:
- codeId
- spotId
- code
我想介绍一下这个字段
- spotName
代码(并通过spotId加入)。
如何更新mongo shell中的所有现有文档?
当我尝试$ lookup时,我总是得到整个Spot文档,而不仅仅是名称字段。
答案 0 :(得分:3)
如果您希望获得每个文档中获得spotName
的格式,则可以使用聚合管道。 $lookup
是一个好的开始。在这里它生成完整的数组,您可以$unwind
并投射必要的东西
[{$lookup: {
from: 'Spots',
localField: 'spotId',
foreignField: 'spotId',
as: 'new_field'
}},
{$unwind: '$new_field'},
{$project: {
codeId: 1,
spotId: 1,
code: 1,
spotName: '$new_field.name'
}}
]
如果您只需要使用结果,上面的解决方案就代表了这种情况。
如果您确实想要对集合执行update
,唯一的方法是编写一个find
,其中包含代码中的所有文档,然后一旦获得文档,它就会搜索使用findOne
的Spots中的doc,然后发出更新语句。
Codes.find().each(function(err, doc) {
Spots.findOne({spotId: doc.spotId}, function (err, item) {
Codes.update({codeId: doc.codeId}, {$set: {spotName: item.name}}, function (err, res) {})
})
});
答案 1 :(得分:0)
您必须运行脚本
var spotMap ={}; Spots.find({},{spotId:1,name:1}).each(function(spot){spotMap[spot.spotId]=spot.name}); Codes.find({}).each(function(code){code.spotName=spotMap[code.spotId]; db.Codes.save(code);});
另请注意,如果集合太大,由于内存中16MB数据的mongo限制,一次获取所有数据会出现问题,然后您必须多次批量运行脚本。
Codes.find({}).limit(1000).each(function(code){//do normal stuff}
Codes.find({}).skip(1000).limit(1000).each(function(code){//do normal stuff}
Codes.find({}).skip(2000).limit(1000).each(function(code){//do normal stuff}
依旧......