如何将数组转换为 mongodb/mongoose 聚合中的对象?
How to transform array to objects in mongodb/mongoose aggregation?
共有三个合集。
离开
- _id
- 用户(参考用户模型)
- 状态
请假
- _id
- 离开(参考离开模型)
- auditUser(参考用户模型)
- 角色
用户
- _id
- 姓名
在休假集合上执行查找阶段后:
Leave.aggregate([
$lookup: {
from: 'leaveapprovals',
localField: '_id',
foreignField: 'leave',
as: 'approverRecommender'
}
])
{
_id: ObjectId('6262851ab059b81fd9076532'),
user: ObjectId('21ca9490192add08fa385aec'),
status: "pending",
approverRecommender: [
{
_id: ObjectId('6262851ab059b81fd907653d'),
leave: ObjectId('6262851ab059b81fd9076532'),
auditUser: ObjectId('61ca9490192add08fa385aeb'),
role: "recommender"
},
{
_id: ObjectId('6262851ab059b81fd907653d'),
leave: ObjectId('6262851ab059b81fd9076532'),
auditUser: ObjectId('71ca9490192add08fa385aec'),
role: "approver"
}
]
}
我想要得到的结果是:
{
_id: ObjectId('6262851ab059b81fd9076532'),
user: ObjectId('21ca9490192add08fa385aec'),
status: "pending",
recommender: {
_id: ObjectId('61ca9490192add08fa385aeb'),
name: "Andrew"
},
approver: {
_id: ObjectId('71ca9490192add08fa385aec'),
name: "James"
}
}
如何改造?
$lookup
- 需要一个嵌套的 $lookup
。首先 $lookup
使用管道加入 leave
和 leaveapprovals
集合。而内部 $lookup
加入 user
集合和 return auditUser
和 role
字段。
$set
-
2.1。对于 approver
字段,为 approver
角色过滤 approverRecommender
数组字段,并通过 $first.
获取第一个文档
2.2。对于 recommender
字段,过滤 recommender
角色的 approverRecommender
数组字段,并通过 $first.
获取第一个文档
$project
- 修饰输出文档。使用 $first
到 return approver
和 recommender
的第一个文档作为结果 2 的两个字段 return 作为数组。
db.leave.aggregate([
{
$lookup: {
from: "leaveapprovals",
let: {
leaveId: "$_id"
},
pipeline: [
{
$match: {
$expr: {
$eq: [
"$$leaveId",
"$leave"
]
}
}
},
{
$lookup: {
from: "user",
localField: "auditUser",
foreignField: "_id",
as: "auditUser"
}
},
{
$project: {
auditUser: 1,
role: 1
}
}
],
as: "approverRecommender"
}
},
{
"$set": {
approver: {
"$first": {
"$filter": {
"input": "$approverRecommender",
"cond": {
$eq: [
"$$this.role",
"approver"
]
}
}
}
},
recommender: {
"$first": {
"$filter": {
"input": "$approverRecommender",
"cond": {
$eq: [
"$$this.role",
"recommender"
]
}
}
}
}
}
},
{
"$set": {
approver: {
"$first": {
"$filter": {
"input": "$approverRecommender",
"cond": {
$eq: [
"$$this.role",
"approver"
]
}
}
}
},
recommender: {
"$first": {
"$filter": {
"input": "$approverRecommender",
"cond": {
$eq: [
"$$this.role",
"recommender"
]
}
}
}
}
}
},
{
$project: {
_id: 1,
user: 1,
status: 1,
"approver": {
$first: "$approver.auditUser"
},
"recommender": {
$first: "$recommender.auditUser"
}
}
}
])
共有三个合集。
离开
- _id
- 用户(参考用户模型)
- 状态
请假
- _id
- 离开(参考离开模型)
- auditUser(参考用户模型)
- 角色
用户
- _id
- 姓名
在休假集合上执行查找阶段后:
Leave.aggregate([
$lookup: {
from: 'leaveapprovals',
localField: '_id',
foreignField: 'leave',
as: 'approverRecommender'
}
])
{
_id: ObjectId('6262851ab059b81fd9076532'),
user: ObjectId('21ca9490192add08fa385aec'),
status: "pending",
approverRecommender: [
{
_id: ObjectId('6262851ab059b81fd907653d'),
leave: ObjectId('6262851ab059b81fd9076532'),
auditUser: ObjectId('61ca9490192add08fa385aeb'),
role: "recommender"
},
{
_id: ObjectId('6262851ab059b81fd907653d'),
leave: ObjectId('6262851ab059b81fd9076532'),
auditUser: ObjectId('71ca9490192add08fa385aec'),
role: "approver"
}
]
}
我想要得到的结果是:
{
_id: ObjectId('6262851ab059b81fd9076532'),
user: ObjectId('21ca9490192add08fa385aec'),
status: "pending",
recommender: {
_id: ObjectId('61ca9490192add08fa385aeb'),
name: "Andrew"
},
approver: {
_id: ObjectId('71ca9490192add08fa385aec'),
name: "James"
}
}
如何改造?
$lookup
- 需要一个嵌套的$lookup
。首先$lookup
使用管道加入leave
和leaveapprovals
集合。而内部$lookup
加入user
集合和 returnauditUser
和role
字段。$set
-2.1。对于
获取第一个文档approver
字段,为approver
角色过滤approverRecommender
数组字段,并通过$first.
2.2。对于
获取第一个文档recommender
字段,过滤recommender
角色的approverRecommender
数组字段,并通过$first.
$project
- 修饰输出文档。使用$first
到 returnapprover
和recommender
的第一个文档作为结果 2 的两个字段 return 作为数组。
db.leave.aggregate([
{
$lookup: {
from: "leaveapprovals",
let: {
leaveId: "$_id"
},
pipeline: [
{
$match: {
$expr: {
$eq: [
"$$leaveId",
"$leave"
]
}
}
},
{
$lookup: {
from: "user",
localField: "auditUser",
foreignField: "_id",
as: "auditUser"
}
},
{
$project: {
auditUser: 1,
role: 1
}
}
],
as: "approverRecommender"
}
},
{
"$set": {
approver: {
"$first": {
"$filter": {
"input": "$approverRecommender",
"cond": {
$eq: [
"$$this.role",
"approver"
]
}
}
}
},
recommender: {
"$first": {
"$filter": {
"input": "$approverRecommender",
"cond": {
$eq: [
"$$this.role",
"recommender"
]
}
}
}
}
}
},
{
"$set": {
approver: {
"$first": {
"$filter": {
"input": "$approverRecommender",
"cond": {
$eq: [
"$$this.role",
"approver"
]
}
}
}
},
recommender: {
"$first": {
"$filter": {
"input": "$approverRecommender",
"cond": {
$eq: [
"$$this.role",
"recommender"
]
}
}
}
}
}
},
{
$project: {
_id: 1,
user: 1,
status: 1,
"approver": {
$first: "$approver.auditUser"
},
"recommender": {
$first: "$recommender.auditUser"
}
}
}
])