Javascript 多聚合查询MongoDB
我有以下情况:Javascript 多聚合查询MongoDB,javascript,mongodb,mongodb-query,aggregation-framework,Javascript,Mongodb,Mongodb Query,Aggregation Framework,我有以下情况: 收集部门: { "_id" : 0, "name" : "Dep_A_1", "description" : "Department A1" } { "_id" : 1, "name" : "Dep_B_1", "description" : "Department B1" } { "_id" : 2, "name" : "Dep_C_1", "description" : "Department C1" } 收藏技能: { "_id" : 0, "na
- 收集
:部门
{ "_id" : 0, "name" : "Dep_A_1", "description" : "Department A1" } { "_id" : 1, "name" : "Dep_B_1", "description" : "Department B1" } { "_id" : 2, "name" : "Dep_C_1", "description" : "Department C1" }
- 收藏
:技能
{ "_id" : 0, "name" : "Creativity", "description" : "description", "type" : "soft", "categories" : [ 0, 2 ] }
- 集合
:角色
{ "_id" : 0, "name" : "Software Developer Automation and Control", "description" : "Automation and Control expert", "departments" : [ 0, 2 ], "skills" : [ { "_id" : 18, "weight" : 30 } ] }
{
"_id" : 0,
"name" : "Software Developer Automation and Control",
"description" : "Automation and Control expert",
"departments" : [
{
"_id" : 0,
"name" : "Dep_A_1",
"description" : "Department A1"
},
{
"_id" : 2,
"name" : "Dep_C_1",
"description" : "Department C1"
}
],
"skills" : [
{
"_id" : 0,
"name" : "Creativity",
"description" : "description",
"type" : "soft",
"weight" : 30
}
]
}
我需要将角色.departments
和角色.skills
数组替换为部门
和角色
集合中的相应对象。有没有办法查询Mongo并得到这样的结果
无论如何,我使用的是Mongo3.6和Pymango。
谢谢。只需使用两次:
编辑:现在正确保留了角色.技能.权重
:
db.getCollection('roles').aggregate([
{$unwind: '$skills'},
{$lookup: {
from: 'skills',
localField: 'skills._id',
foreignField: '_id',
as: 'skillsInfo'
}},
{$unwind: '$skillsInfo'},
{$addFields: {skills: {$mergeObjects: ['$skills', '$skillsInfo']}}},
{$project: {skillsInfo: 0}},
{$group: {
_id: '$_id',
name: {$first: '$name'},
description: {$first: '$description'},
departments: {$first: '$departments'},
skills: {$push: '$skills'}
}},
{$lookup: {
from: 'departments',
localField: 'departments',
foreignField: '_id',
as: 'departments'
}}
])
为了避免成本高昂的
$REWIND
和$group
阶段,您可以这样做:
db.roles.aggregate([{
$lookup: {
from: 'departments',
localField: 'departments',
foreignField: '_id',
as: 'departments'
}
}, {
$lookup: {
from: 'skills',
let: {
"skills": "$skills" // keep a reference to the "skills" field of the current document and make it accessible via "$$skills"
},
pipeline: [{
$match: {
$expr: {
$in: [ "$_id", "$$skills._id" ] // this just does the "joining"
}
}
}, {
$addFields: { // add a new field
"weight": { // called "weight"
$arrayElemAt: [ // which shall be set to the correct "weight"
"$$skills.weight", // that can be found in the "weight" field of the "skills" array
{ $indexOfArray: [ "$$skills._id", "$_id" ] } // at the position that has the matching "_id" value
]
}
}
}],
as: 'skills'
}
}])
到目前为止你试过什么?你能展示一些东西吗?这对部门来说非常有效,但这样我就失去了角色、技能和权重的价值。有解决方案吗?您好,您的答案会产生以下错误:“$arrayElemAt的第二个参数必须是数值,但是对象”您确定您使用的是最新版本的代码吗?我想在我后来添加的“indexOfArray”前面最初缺少了一个
$
。它肯定能在我的机器上工作——我只是再试一次。
db.roles.aggregate([{
$lookup: {
from: 'departments',
localField: 'departments',
foreignField: '_id',
as: 'departments'
}
}, {
$lookup: {
from: 'skills',
let: {
"skills": "$skills" // keep a reference to the "skills" field of the current document and make it accessible via "$$skills"
},
pipeline: [{
$match: {
$expr: {
$in: [ "$_id", "$$skills._id" ] // this just does the "joining"
}
}
}, {
$addFields: { // add a new field
"weight": { // called "weight"
$arrayElemAt: [ // which shall be set to the correct "weight"
"$$skills.weight", // that can be found in the "weight" field of the "skills" array
{ $indexOfArray: [ "$$skills._id", "$_id" ] } // at the position that has the matching "_id" value
]
}
}
}],
as: 'skills'
}
}])