我有一个
Project
实体(projects
集合)。每个 Project
都属于由 Project.orgId
代表的组织,并且有一个作者 Project.author
,取自 users
集合。
我想使用 Mongoose 查询属于某个组织的项目,这是我想出的管道:
Project.aggregate([
{
$match: { organization: new mongoose.Types.ObjectId("an-object-id") }
},
{
$lookup: {
from: User.collection.collectionName,
localField: "authorId",
foreignField: "_id",
as: "author",
},
/* Tried moving unset here. Doesn't work. Error: Arguments must be aggregate pipeline operators
{
"$unset": ["__v", "hash"],
},
*/
},
{
$unset: ["author.__v", "author.hash"]
}
])
这个管道的问题在于,
project.author
不再是一个对象,而是变成了一个单元素数组。
{
"codename": "Longhorn",
"launch": 1970-01-01T00:00:00Z,
"author": {
"firstName": "John",
"lastName": "Smith"
}
}
{
"codename": "Longhorn",
"launch": 1970-01-01T00:00:00Z,
"author": [
{
"firstName": "John",
"lastName": "Smith"
}
]
}
什么是正确的管道?
$unwind
阶段:
Project.aggregate([
{
$match: { organization: new mongoose.Types.ObjectId("an-object-id") }
},
{
$lookup: {
from: User.collection.collectionName,
localField: "authorId",
foreignField: "_id",
as: "author",
}
},
{
$unwind: "$author",
},
{
$unset: ["author.__v", "author.hash"]
}
])
这就是
$lookup
的工作原理。它总是会为您提供一个数组,因为它可能会匹配其他集合中的多个文档。
您可以在后续步骤中使用
$addFields
将数组转换为数组中的第一个文档。
Project.aggregate([
{
$match: { organization: new mongoose.Types.ObjectId("an-object-id") }
},
{
$lookup: {
from: User.collection.collectionName,
localField: "authorId",
foreignField: "_id",
as: "author",
},
},
{
$addFields: {
author: { $first: "$author" },
},
},
{
$unset: ["author.__v", "author.hash"]
}
])