我有“工作”和“用户”集合。每个用户都可以为给定的“jobCategoryId”创建一个工作,然后该工作将保存在“工作”集合中,并包含其创建者的“userId”和“jobCategoryId”。
我正在尝试合并这 2 个集合,因此当我获取作业时,我将拥有包含所有用户数据的“用户”字段,而不是该作业的“用户 ID”字段。这就是我目前的做法:
Job.aggregate([{
$match: {
jobCategoryId: mongoose.Types.ObjectId(jobCategoryId)
}
}, {
$lookup: {
from: 'users',
localField: 'userId',
foreignField: '_id',
as: 'user'
}
}, {
$project: {
_id: 1,
description: 1,
title: 1,
user: { $arrayElemAt: ['$user', 0] }
}
}, {
$project: {
_id: 1,
title: 1,
description: 1,
'user.name': '$user.name'
}
}])
这将返回以下内容:
[{
_id: 'some id',
title: 'title',
description: 'description',
user: {
name: 'Mike'
}
}]
结果是正确的,但我真的很感兴趣是否有任何其他方法可以在使用 $arrayElemAt 时直接保留用户对象中的某些字段,或者我是否注定要在管道中使用 2 个投影? 谁能帮我解决这个小问题?我真的很感激。
最佳答案
这是来自 arrayElemAt 的语法
The expression can be any valid expression as long as it resolves to an array.
这意味着您可以根据需要构造数组元素。在您的情况下,您只需要名称。所以这应该有效:
[{
$match: {
jobCategoryId: mongoose.Types.ObjectId(jobCategoryId)
}
}, {
$lookup: {
from: 'users',
localField: 'userId',
foreignField: '_id',
as: 'user'
}
}, {
$project: {
_id: 1,
description: 1,
title: 1,
user: {
name: {
$arrayElemAt: ["$user.name", 0]
}
}
}
}]
跟进更新:
有人问如何在 name
之上添加其他属性。这是项目:
{
$project: {
_id: 1,
description: 1,
title: 1,
user: {
name: {
$arrayElemAt: ["$user.name", 0]
},
email: {
$arrayElemAt: ["$user.email", 0]
}
}
}
}
第二次跟进,如 Drag0 在评论中所问:如果上述内容不够好,因为结果生成了一个用户:[] 大小为 1 的数组而不是对象用户:{}可以使用以下。
{
$project: {
_id: 1,
description: 1,
title: 1,
user: {
$let: {
vars: {
firstUser: {
$arrayElemAt: ["$user", 0]
}
},
in: {
name: "$$firstUser.name",
email: "$$firstUser.email"
}
}
}
}
}
关于mongodb - 如何使用 $arrayElemAt 并从 MongoDB $projection 中的该元素中删除字段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39649562/