我有以下用于用户集合的 MongoDB 架构
{
...otherProperties,
skills: [
{
skill: { type: db.Schema.Types.ObjectId, ref: 'Skill' },
level: { type: String }
}
]
}
我正在尝试使用聚合将此集合加入到技能集合中 但我想保留另一个字段
level
并将每个字段与其对象连接起来
我尝试过以下聚合
[{$lookup:{ from: 'Skill',localField: 'skills.skill', foreignField: '_id', as: 'skills.skill' }}]
我得到的结果如下
{
"_id": {
"$oid": "6130f296eff45efaa80cb4e6"
},
"skills": {
"skill": [
{
"_id": {
"$oid": "60d9a0996e5c5f0025f3c882"
},
"job_post_enabled": true,
"job_seeker_enabled": true,
"job_seeker": "A/R Management",
"job_post": "A/R Management",
"__v": 0,
"translations": {
"AR": {
"job_post": "A/R Management",
"job_seeker": "A/R Management"
},
"EN": {
"job_post": "A/R Management",
"job_seeker": "A/R Management"
}
},
"created_at": {
"$date": "2021-06-28T10:12:58.221Z"
},
"updated_at": {
"$date": "2022-01-25T21:52:55.447Z"
}
},
{
"_id": {
"$oid": "60d9a0996e5c5f0025f3c886"
},
"job_post_enabled": true,
"job_seeker_enabled": true,
"job_seeker": "A/V systems",
"job_post": "A/V systems",
"__v": 0,
"translations": {
"AR": {
"job_post": "A/V systems",
"job_seeker": "A/V systems"
},
"EN": {
"job_post": "A/V systems",
"job_seeker": "A/V systems"
}
},
"created_at": {
"$date": "2021-06-28T10:12:58.221Z"
},
"updated_at": {
"$date": "2022-01-25T21:52:55.453Z"
}
}
]
}
}
有没有办法使用聚合将每个技能与其自己的记录连接起来?并保持字段原样
我目前的数据
{
"skills": [
{
"skill": ObjectId("60d9a0996e5c5f0025f3c882"),
"level": "High"
},
{
"skill": ObjectId("60d9a0996e5c5f0025f3c886"),
"level": "Mid"
}
]
}
所需的输出
{
"skills": [
{
"skill": {
"_id": {
"$oid": "60d9a0996e5c5f0025f3c882"
},
"job_post_enabled": true,
"job_seeker_enabled": true,
"job_seeker": "A/R Management",
"job_post": "A/R Management",
"__v": 0,
"translations": {
"AR": {
"job_post": "A/R Management",
"job_seeker": "A/R Management"
},
"EN": {
"job_post": "A/R Management",
"job_seeker": "A/R Management"
}
},
"created_at": {
"$date": "2021-06-28T10:12:58.221Z"
},
"updated_at": {
"$date": "2022-01-25T21:52:55.447Z"
}
},
"level": "High"
},
{
"skill": {
"_id": {
"$oid": "60d9a0996e5c5f0025f3c886"
},
"job_post_enabled": true,
"job_seeker_enabled": true,
"job_seeker": "A/V systems",
"job_post": "A/V systems",
"__v": 0,
"translations": {
"AR": {
"job_post": "A/V systems",
"job_seeker": "A/V systems"
},
"EN": {
"job_post": "A/V systems",
"job_seeker": "A/V systems"
}
},
"created_at": {
"$date": "2021-06-28T10:12:58.221Z"
},
"updated_at": {
"$date": "2022-01-25T21:52:55.453Z"
}
},
"level": "Mid"
}
]
}
解决方案,但需要注意技能_id应该存在于查找集合中;否则,技能 _id 将不会出现在输出中,即没有立即的方法来告诉缺少某些内容。
c = db.foo.aggregate([
// Optional match here:
//{$match: {_id:0}},
// Do the basic lookup:
{$lookup: {
from: "Xskills",
localField: "skills.skill",
foreignField: "_id",
as: "zz"
}}
// zz now contains an array of zero to N matches against the skills
// table. Use $zip to merge the separate skills and detail array fields, e.g.
// {
// skills: [ {skill:"S1",level:"High"},
// zz: [ {job_seeker:"whatever",job_post_enabled:true,...}, {QQQ} ]
// becomes an array of arrays [ [skill,detail], [skill,detail], ...]
// {
// skills: [ [ {skill:"S1",level:"High"}, {job_seeker:"whatever",job_post_enabled:true,...} ], [ {skill:"S2",level:"Mid"}, {job_seeker:"whatever",job_post_enabled:true,...} ] ]
// }
,{$project: {
"skills": {$zip: {inputs: [ "$skills", "$zz" ]}}
}}
// Now we have a single array field with a well-known structure that we can
// reformat to produce the output we seek:
,{$project: {
"skills": {$map: {input: "$skills", in:
{
"skill": {$arrayElemAt:["$$this",1]},
"level": {$arrayElemAt:["$$this.level",0]}
}
}}
}}
]);