如何解决如何编写聚合管道以将合并的文档作为文档插入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_2
和lookup
进行汇总,然后使用{来获取第一个找到的文档{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 举报,一经查实,本站将立刻删除。