我有两个Mongodb 3.6集合,其中一个引用另一个作为示例数据,其中certs.$Entities.Id: entities._id
:
certs: {
_id: ObjectId('xxx'),
Category: "Certification",
Entities: [{Id: ObjectId('abc'), prev: true, Own_type: "Contact"}
{Id: ObjectId('def), prev: false, Own_Type: "Operator"}]
...bunch more fields
}
另外一个:
entities: {_id: ObjectId('abc'),
FName: 'Bob',
LName: 'Smith',
...bunch more fields},
{_id: ObjectId('def'),
FName: 'Bill',
LName: 'Jones',
...bunch more fields}
我想使用一个简单的查询将信息从实体获取到证书中,通常会这样做,但是它会产生两个对象或覆盖cert.Entities
。问题是我需要能够保留cert.Entities
中的数据并将其与entities
合并。
所需的结果将是:
certs: {
_id: ObjectId('xxx'),
Category: "Certification",
Entities: [{Id: ObjectId('abc'),
prev: true,
Own_type: "Contact",
FName: 'Bob',
LName: 'Smith',
...bunch more fields}
{Id: ObjectId('def),
prev: false,
Own_Type: "Operator",
FName: 'Bill',
LName: 'Jones',
...bunch more fields
}]
...bunch more fields
}
我通过执行以下聚合来完成此操作,但是看起来不对,因为我必须在结果中需要使用的多个字段上使用$ first累加器。
certs.aggregate([{
$unwind: {
path: '$Entities',
preserveNullAndEmptyArrays: false
}
},
{
$lookup: {
from: 'entities',
localField: 'Entities.Id',
foreignField: '_id',
as: 'Ent'
}
},
{
$unwind: {
path: '$Ent',
preserveNullAndEmptyArrays: false
}
},
{
$addFields: {
Ent2: {
$mergeObjects: ['$Ent', '$Entities']
}
}
},
{
$group: {
_id: '$_id',
Entities: {
$push: '$Ent2'
},
Cert_ID: {
$first: '$Cert_ID'
},
Cert_Details: {
$first: '$Cert_Details'
},
Allocations: {
$first: '$Allocations'
},
Flowmeters: {
$first: '$Flowmeters'
},
Category: {
$first: '$Category'
},
Water_Sources: {
$first: '$Water_Sources'
},
Active: {
$first: '$Active'
},
County: {
$first: '$County'
},
Legal: {
$first: '$Legal'
},
GWMA: {
$first: '$GWMA'
},
Alias: {
$first: '$Alias'
},
Usage: {
$first: '$Usage'
}
}
}])
有人可以给我一些建议以改善总体状况还是给我一个替代管道?
答案 0 :(得分:0)
您需要$map
和$filter
来替换$lookup
之后的联接实体
db.certs.aggregate([
{$match : {_id : "xxx"}},
{$lookup : {from:"entities", localField:"Entities",foreignField:"_id", as: "joins"}},
{$addFields : {Entities:
{$map : {
input : "$Entities",
as : "e",
in : {$arrayElemAt :[{
$filter : {
input : "$joins",
as : "j",
cond : {$eq :["$$e", "$$j._id"]}
}},0]}
}}
}},
{$project : {joins:0}}
]).pretty()
EDIT-1
保留两个数组元素中的字段
db.certs.aggregate([
{$match : {_id : "xxx"}},
{$lookup : {from:"entities", localField:"Entities._id",foreignField:"_id", as: "joins"}},
{$addFields : {Entities:
{$map : {
input : "$Entities",
as : "e",
in : {$mergeObjects: [
"$$e",
{$arrayElemAt :[{$filter : {input : "$joins",as : "j", cond : {$eq :["$$e", "$$j._id"]}}},0]}
]
}}}
}},
{$project : {joins:0}}
]).pretty()