我有一个子集合,该子集合具有链接到同一主集合的3个不同字段。如果将它们合并到根元素第3个中,则第一个覆盖第2个,这很有意义,因为所有三个3查找均指向同一集合。如果我不合并这些集合,则需要遍历结果集并在客户端上逐一填充模型字段,这是我想避免的。
有没有办法,我可以合并所有3个查找结果,并以某种方式可以更改字段名称,所以一个不会被其他字段覆盖。
以下是我的代码:-
module.exports.getAssignmentByClient = function(req, res) {
var query = url.parse(req.url,true).query;
Assignment.aggregate([
{
$match :
{
clientId: 4,
} ,
},
{
$lookup:
{
from: "staffs",
localField: "assignedMember1",
foreignField: "staffId",
as: "member1"
},
},
{
$lookup:
{
from: "staffs",
localField: "assignedMember2",
foreignField: "staffId",
as: "member2"
},
},
{
$lookup:
{
from: "staffs",
localField: "assignedLeader",
foreignField: "staffId",
as: "leader"
},
},
{
$replaceRoot:
{
newRoot:
{
$mergeObjects: [
{$arrayElemAt: [ "$member1", 0 ]},
{$arrayElemAt: [ "$member2", 0 ]},
{$arrayElemAt: [ "$leader", 0 ]},
"$$ROOT" ]
}
}
},
{
$project:
{
member1: 0,
member2: 0,
leader: 0
}
}
],
function (err, response) {
if (err) throw err;
if (!response) {
res.status(200).json({ success: false, message: 'Somthing went wrong. Please contact admin.'});
}
else {
res.status(200).json({ success: true, message: 'Successfull', data: response});
}
});
};
不合并的结果集:
{
"success": true,
"message": "Successfull",
"data": [
{
"_id": "5b5d083cf7edf20be8999746",
"assignmentId": 25,
"taskId": 1,
"assignedLeader": 2,
"assignedMember1": 1,
"assignedMember2": 1,
"priority": "M",
"startDate": "2018-01-08T05:00:00.000Z",
"endDate": "2018-09-08T04:00:00.000Z",
"status": "R",
"billingMode": "F",
"fixedAmount": 12,
"hourlyRate": 0,
"hours": 0,
"hourlyAmount": 0,
"clientId": 4,
"__v": 0,
"member1": [
{
"_id": "5b5906a66a6c614f8cb9bd99",
"staffId": 1,
"staffName": "A",
"designation": "E",
"phone": 9876,
"address1": "US",
"address2": "",
"email": "a@a.com",
"manager": "2",
"__v": 0
}
],
"member2": [
{
"_id": "5b5906a66a6c614f8cb9bd99",
"staffId": 1,
"staffName": "B",
"designation": "E",
"phone": 9876,
"address1": "US",
"address2": "",
"email": "b@b.com",
"manager": "2",
"__v": 0
}
],
"leader": [
{
"_id": "5b5906cb6a6c614f8cb9bd9a",
"staffId": 2,
"staffName": "C",
"designation": "M",
"phone": 2488263783,
"address1": "U",
"address2": "",
"email": "c@c.com",
"manager": "",
"__v": 0
}
]
}
]
}
具有合并的结果集:-[使用领导者的最后一次查找替换了成员1和成员2]
{
"success": true,
"message": "Successfull",
"data": [
{
"_id": "5b5d083cf7edf20be8999746",
"assignmentId": 25,
"taskId": 1,
"assignedLeader": 2,
"assignedMember1": 1,
"assignedMember2": 1,
"priority": "M",
"startDate": "2018-01-08T05:00:00.000Z",
"endDate": "2018-09-08T04:00:00.000Z",
"status": "R",
"billingMode": "F",
"fixedAmount": 12,
"hourlyRate": 0,
"hours": 0,
"hourlyAmount": 0,
"clientId": 4,
"__v": 0,
"staffId": 2,
"staffName": "C",
"designation": "M",
"phone": 2488263783,
"address1": "U",
"address2": "",
"email": "c@c.com",
"manager": "",
}
]
}
更新的代码:-
module.exports.getAssignmentByClient = function(req, res) {
var query = url.parse(req.url,true).query;
Assignment.aggregate([
{
$match :
{
clientId: 4,
} ,
},
{
$lookup:
{
from: "staffs",
localField: "assignedMember1",
foreignField: "staffId",
as: "member1"
},
},
{
$lookup:
{
from: "staffs",
localField: "assignedMember2",
foreignField: "staffId",
as: "member2"
},
},
{
$lookup:
{
from: "staffs",
localField: "assignedLeader",
foreignField: "staffId",
as: "leader"
},
},
{"$replaceRoot":{
"newRoot":{
"$reduce":{
"input":[{"k":"member1","v":"$member1"},{"k":"member2","v":"$member2"},{"k":"leader","v":"$leader"}],
"initialValue":"$$ROOT",
"in":{
"$mergeObjects":[
{"$let":{
"vars":{"v":{"$arrayElemAt":["$$this.v",0]}},
"in":{"$arrayToObject":{
"$map":{
"input":{"$objectToArray":"$$v"},
"as":"val",
"in":{
"k":{"$concat":["$$this.k","-","$$val.k"]},
"v":"$$val.v"}
}
}}
}},
"$$value"
]
}
}
}
}},
{
"$project": {
"member1": 0,
"member2": 0,
"leader": 0
}
}
],
function (err, response) {
if (err) throw err;
if (!response) {
res.status(200).json({ success: false, message: 'Somthing went wrong. Please contact admin.'});
}
else {
res.status(200).json({ success: true, message: 'Successfull', data: response});
}
});
};
具有更新代码的JSON结果:-
{
"success": true,
"message": "Successfull",
"data": [
{
"leader-_id": "5b5906cb6a6c614f8cb9bd9a",
"leader-staffId": 2,
"leader-staffName": "A",
"leader-designation": "M",
"leader-phone": 2488263783,
"leader-address1": "US",
"leader-address2": "",
"leader-email": "a@a.com",
"leader-manager": "",
"leader-__v": 0,
"member2-_id": "5b5906a66a6c614f8cb9bd99",
"member2-staffId": 1,
"member2-staffName": "B",
"member2-designation": "E",
"member2-phone": 9876,
"member2-address1": "US",
"member2-address2": "",
"member2-email": "b@b.com",
"member2-manager": "2",
"member2-__v": 0,
"member1-_id": "5b5906a66a6c614f8cb9bd99",
"member1-staffId": 1,
"member1-staffName": "C",
"member1-designation": "E",
"member1-phone": 9876,
"member1-address1": "US",
"member1-address2": "",
"member1-email": "c@c.com",
"member1-manager": "2",
"member1-__v": 0,
"_id": "5b5d083cf7edf20be8999746",
"assignmentId": 25,
"taskId": 1,
"assignedLeader": 2,
"assignedMember1": 1,
"assignedMember2": 1,
"priority": "M",
"startDate": "2018-01-08T05:00:00.000Z",
"endDate": "2018-09-08T04:00:00.000Z",
"status": "R",
"billingMode": "F",
"fixedAmount": 12,
"hourlyRate": 0,
"hours": 0,
"hourlyAmount": 0,
"clientId": 4,
"__v": 0
},
{
"_id": "5b5e0f9ced856f17187c8888",
"assignmentId": 28,
"taskId": 2,
"assignedLeader": "2",
"assignedMember1": "1",
"assignedMember2": "1",
"priority": "H",
"startDate": "2018-01-08T05:00:00.000Z",
"endDate": "2018-07-08T04:00:00.000Z",
"status": "C",
"billingMode": "F",
"fixedAmount": 900,
"hourlyRate": 0,
"hours": 0,
"hourlyAmount": 0,
"clientId": 4,
"__v": 0
}
]
}
嵌套的集合字段参考* (我嵌套了assignmentMaster的查找,然后我想将此集合字段作为其他匹配字段引用到其他集合中,但它没有返回期望的结果。好像我在无法正确引用AssignmentMaster字段。)
module.exports.getAssignmentByClient = function(req, res) {
var query = url.parse(req.url,true).query;
var clientId = parseInt(query.clientId);
AssignmentDetail.aggregate([
{
$match :
{
clientId: clientId,
} ,
},
{
$lookup:
{
from: "assignmentmasters",
localField: "assignmentId",
foreignField: "assignmentId",
as: "assignmentMasterData"
},
},
{
$lookup: {
from: "lists",
let: { "status": "$assignmentMasterData" },
pipeline: [
{
$match:
{ $expr: { $and: [
{ $eq:
[ "$listName", "AssignmentStatus" ]
},
{ $eq:
[ "$listItem", "$$status.status" ]
}
]
}
}
},
],
as: "assignmentStatus"
}},
{"$replaceRoot":{
"newRoot":{
"$reduce":{
"input":[{"k":"assignmentStatus","v":"$assignmentStatus"},{"k":"assignmentMasterData","v":"$assignmentMasterData"}],
"initialValue":"$$ROOT",
"in":{
"$mergeObjects":[
{"$let":{
"vars":{"v":{"$arrayElemAt":["$$this.v",0]}},
"in":{"$arrayToObject":{
"$map":{
"input":{"$objectToArray":"$$v"},
"as":"val",
"in":{
"k":{"$concat":["$$this.k","-","$$val.k"]},
"v":"$$val.v"}
}
}}
}},
"$$value"
]
}
}
}
}},
{
"$project": {
"assignmentStatus": 0,
"assignmentMasterData": 0
}
}
],
function (err, response) {
if (err) throw err;
if (!response) {
res.status(200).json({ success: false, message: 'Somthing went wrong. Please contact admin.'});
}
else {
res.status(200).json({ success: true, message: 'Successfull', data: response});
}
});
};
答案 0 :(得分:1)
您可以使用下面的聚合查询为每个查找的所有键加上别名作为前缀。
使用$concat
,$map
,$objectToArray
和$arrayToObject
运算符将查找别名作为每个查找列的前缀。
下面显示的member1示例。类似地,添加所有其他查找别名。
类似
{"$replaceRoot":{
"newRoot":{
"$mergeObjects":[
{"$let":{
"vars":{"v":{"$arrayElemAt":["$member1",0]}},
"in":{"$arrayToObject":{
"$map":{
"input":{"$objectToArray":"$$v"},
"as":"val",
"in":{
"k":{"$concat":["member1","-","$$val.k"]},
"v":"$$val.v"
}}
}}
}},
--- other look up alias here
]
}
}}
如果您不想为所有别名重复相同的代码,则可以创建一个文档数组,然后$reduce
来创建合并的文档。
类似
{"$replaceRoot":{
"newRoot":{
"$reduce":{
"input":[{"k":"member1","v":"$member1"},{"k":"member2","v":"$member2"},{"k":"leader","v":"$leader"}],
"initialValue":"$$ROOT",
"in":{
"$mergeObjects":[
{"$let":{
"vars":{"v":{"$arrayElemAt":["$$this.v",0]}},
"in":{"$arrayToObject":{
"$map":{
"input":{"$objectToArray":"$$v"},
"as":"val",
"in":{
"k":{"$concat":["$$this.k","-","$$val.k"]},
"v":"$$val.v"}
}
}}
}},
"$$value"
]
}
}
}
}}
答案 1 :(得分:0)
有没有办法,我可以合并所有3个查找结果,并以某种方式可以更改字段名称,所以一个不会被其他字段覆盖。
您可以在现有聚合查询(https://docs.mongodb.com/manual/reference/operator/aggregation/concatArrays/)中使用 $ concatArrays 连接阵列!
尝试以下代码:
module.exports.getAssignmentByClient = function(req, res) {
var query = url.parse(req.url,true).query;
Assignment.aggregate([
{
$match :
{
clientId: 4,
} ,
},
{
$lookup:
{
from: "staffs",
localField: "assignedMember1",
foreignField: "staffId",
as: "member1"
},
},
{
$lookup:
{
from: "staffs",
localField: "assignedMember2",
foreignField: "staffId",
as: "member2"
},
},
{
$lookup:
{
from: "staffs",
localField: "assignedLeader",
foreignField: "staffId",
as: "leader"
},
},
{
$project: {
items: {
$concatArrays: [ "$member1", "$member2", "$leader" ]
}
}
}
],
function (err, response) {
if (err) throw err;
if (!response) {
res.status(200).json({ success: false, message: 'Somthing went wrong. Please contact admin.'});
}
else {
res.status(200).json({ success: true, message: 'Successfull', data: response});
}
});
};
希望这可以解决您的查询!