微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何编写聚合管道以将合并的文档作为文档插入MongoDB上的新字段获取?

如何解决如何编写聚合管道以将合并的文档作为文档插入MongoDB上的新字段获取?

我是MongoDB的新手,我将举例说明我的问题。场景:

  • 3个收藏夹;

收藏_1

{
    "_id": 1,"idLocal": 1023,"idType": 21 
},{
    "_id": 2,"idLocal": 1029,{
    "_id": 3,"idLocal": 923,"idType": 22 
}

Collection_2

{
    "_id": 1,"idLOp": 1,"idType": 21    
},"idOp": 5,"idType": 21 
}
{
    "_id": 3,"idOp": 1,"idType": 12 
}

因此,要在Collection_3上插入一个新文档,我想创建一个新文档,并以下列条件附加来自Collection_1和Collection_2的文档:

idLocal (Collection_1) == idLocal (New doc to insert) // get desired doc from Collection_1
idOp (Collection_2) == idOp (New doc to insert) AND idType (Collection_1 ) == idType  (Collection_2) // get desired doc from Collection_2

要插入的示例文档

{
    "_id": 5,"idLocal": 1023
}

Collection_3

// new doc saved at Collection_3 result desired:

{
    "_id": 5,"idOP": 1,"Collection_1_doc": { 
          "_id": 1,"idType": 21  
    },"Collection_2_doc": {
           "_id": 1,"idType": 21 
    }
}

那么,如何使用MongoDB管道工具来实现它?我以前从未写过管道,也不知道使用这些函数

解决方法

您不能编写一次一次性添加总值的聚合管道,因为MongoDb 4.2 supports仅在管道中的这些阶段-

  • $ addFields
  • $ set
  • $ project
  • $ unset
  • $ replaceRoot
  • $ replaceWith

并且由于要链接集合1和集合2中的文档,因此不能将更新与聚合管道一起使用。


所以一种方法如下-

第一步是获取链接数据,为此首先对collection_1中的链接文档collection_2lookup进行汇总,然后使用{来获取第一个找到的文档{3}}运算符,

var doc3 = {
    "_id": 5,"idOp": 1,"idLocal": 1023
};

db.Collection_1.aggregate([
    {
        $match: {
            idLocal: doc3.idLocal
        }
    },{
        $lookup: {
           from: 'Collection_2',pipeline: [
              { 
                $match: { 
                    $expr: { 
                        $eq: [ "$idOp",doc.idOp ] 
                    }
                }
              }
           ],as: "Collection_2_data"
        }
    },{
        $project: {
            _id: 0,Collection_1: {
                _id: '$_id',idLocal: '$idLocal',idType: '$idType'
            },Collection_2: {
                $arrayElemAt: [
                    '$Collection_2_data',0
                ]
            }
        }
    }
]);

$arrayElemAt,它给出-

[
  {
    "Collection_1": {
      "_id": 1,"idLocal": 1023,"idType": 21
    },"Collection_2": {
      "_id": 3,"idType": 12
    }
  }
]

由于聚合查询的结果始终包裹在数组中,因此请安全地访问第一个索引并将其附加到您的doc3上并插入。

假设您使用猫鼬,这是上述想法的代码-

const mongoose = require('mongoose');

(async () => {
    try {
        let doc3 = {
            _id: 5,idOp: 1,idLocal: 1023
        };

        const pipeline = [
            {
                $match: {
                    idLocal: doc3.idLocal
                }
            },{
                $lookup: {
                   from: 'Collection_2',pipeline: [
                      { 
                        $match: { 
                            $expr: { 
                                $eq: [ "$idOp",doc.idOp ] 
                            }
                        }
                      }
                   ],as: "Collection_2_data"
                }
            },{
                $project: {
                    _id: 0,Collection_1: {
                        _id: '$_id',idType: '$idType'
                    },Collection_2: {
                        $arrayElemAt: [
                            '$Collection_2_data',0
                        ]
                    }
                }
            }
        ];

        const linkedDocsResult = await Collection_1.aggregate(pipeline).exec();
        
        if (linkedDocsResult.length) {
            doc3 = Object.assign(Object.create(null),doc3,linkedDocsResult[0]);
        }
        
        await Collection_3.create(doc3);
    } catch (err) {
        console.error(err);
    }
})();

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。