【发布时间】:2016-10-22 06:50:18
【问题描述】:
我有一个收藏点:
- spotId
- name
和代码:
- codeId
- spotId
- code
我想介绍一下这个领域
- spotName
到代码(并通过 spotId 加入)。
如何在 mongo shell 中更新我现有的所有文档?
当我尝试 $lookup 时,我总是得到整个 Spot 文档,而不仅仅是名称字段。
【问题讨论】:
标签: mongodb
我有一个收藏点:
- spotId
- name
和代码:
- codeId
- spotId
- code
我想介绍一下这个领域
- spotName
到代码(并通过 spotId 加入)。
如何在 mongo shell 中更新我现有的所有文档?
当我尝试 $lookup 时,我总是得到整个 Spot 文档,而不仅仅是名称字段。
【问题讨论】:
标签: mongodb
如果您想在每个文档中获得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,它会遍历 Codes 中的所有文档,然后一旦获得该文档,它就会使用 Spots 搜索一个文档findOne,然后发出更新声明。
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) {})
})
});
【讨论】:
你必须运行一个脚本
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);});
还要注意,如果集合太大,由于mongo对内存16MB数据的限制,一次获取所有数据会出现问题,然后你必须多次批量运行脚本。
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}
等等……
【讨论】: