【问题标题】:MongoDB Shell: Join a single field from another collectionMongoDB Shell:加入来自另一个集合的单个字段
【发布时间】:2016-10-22 06:50:18
【问题描述】:

我有一个收藏点:

- spotId
- name

和代码:

- codeId
- spotId
- code

我想介绍一下这个领域

- spotName

到代码(并通过 spotId 加入)。

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

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

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    如果您想在每个文档中获得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) {})
      })
    });
    

    【讨论】:

      【解决方案2】:

      你必须运行一个脚本

      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}
      

      等等……

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-03
        • 1970-01-01
        • 2023-01-10
        • 1970-01-01
        相关资源
        最近更新 更多