Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何编写聚合管道以将合并文档作为文档插入MongoDB上的新字段获取?_Mongodb_Mongodb Query_Aggregation Framework - Fatal编程技术网

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

如何编写聚合管道以将合并文档作为文档插入MongoDB上的新字段获取?,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我是MongoDB的新手,我将用一个例子来说明我的问题。情景: 收藏3本 收藏1 { "_id": 1, "idLocal": 1023, "idType": 21 }, { "_id": 2, "idLocal": 1029, "idType": 21 }, { "_id": 3, &

我是MongoDB的新手,我将用一个例子来说明我的问题。情景:

  • 收藏3本
收藏1

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

{
    "_id": 1,
    "idLOp": 1,
    "idType": 21    
},
{
    "_id": 2,
    "idOp": 5,
    "idType": 21 
}
{
    "_id": 3,
    "idOp": 1,
    "idType": 12 
}
因此,要在集合_3上插入新文档,我需要创建一个新文档,附加集合_1和集合_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,
    "idOp": 1,
    "idLocal": 1023
}
收藏3

// new doc saved at Collection_3 result desired:

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

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

您不能编写一个聚合管道,因为MongoDb 4.2只在管道中使用这些阶段-

  • $addFields
  • $set
  • $project
  • 美元未结算
  • $replaceRoot
  • $replacetwith
而且,由于您希望链接集合1和集合2中的文档,因此无法将update与聚合管道一起使用


因此,一种方法如下-

第一步是获取链接数据,首先对
collection_1
collection_2
中的链接文档进行聚合,然后使用运算符获取找到的第一个文档

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
                ]
            }
        }
    }
]);
,即-

[
  {
    "Collection_1": {
      "_id": 1,
      "idLocal": 1023,
      "idType": 21
    },
    "Collection_2": {
      "_id": 3,
      "idOp": 1,
      "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',
                        idLocal: '$idLocal',
                        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);
    }
})();

您可以尝试使用“我不知道使用管道”,因此您要插入文档或将文档作为投影返回?新文档必须保存在集合_3。恐怕您无法一次性完成,您需要两个操作,首先获取链接数据,然后插入它。回答很好。这对我来说有点复杂,否则,我只能获取文档的ID来插入一个新文档,而不是复制整个文档?