MongoDB Shell:从另一个集合加入一个字段

时间:2016-10-21 14:41:54

标签: mongodb

我有一个收集点:

- spotId
- name

和代码:

- codeId
- spotId
- code

我想介绍一下这个字段

- spotName

代码(并通过spotId加入)。

如何更新mongo shell中的所有现有文档?

当我尝试$ lookup时,我总是得到整个Spot文档,而不仅仅是名称字段。

2 个答案:

答案 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}

依旧......