在单个聚合中多次查找后合并 Mongo 个文档
Combine Mongo Documents after multiple lookups in single aggregation
我无法尝试合并我的文档结果。这是我的查询和数据
{"_id":"5c21ab13d03013b384f0de26",
"roles":["5c21ab31d497a61195ce224c","5c21ab4ad497a6f348ce224d","5c21ab5cd497a644b6ce224e"],
"agency":"5b4ab7afd6ca361cb38d6a60","agents":["5b4ab5e897b24f1c4c8e3de3"]}
这里是查询
return db.collection('projects').aggregate([
{
$match: {
agents: ObjectId(agent)
}
},
{
$unwind: "$agents"
},
{
$lookup: {
from: "agents",
localField: "agents",
foreignField: "_id",
as: "agents"
}
},
{
$unwind: {
path: "$roles",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: "roles",
localField: "roles",
foreignField: "_id",
as: "roles"
}
},
{
$lookup: {
from: "agencies",
localField: "agency",
foreignField: "_id",
as: "agency"
}
}
])
如您所见,项目集合中的一个条目有两个数组,在对每个条目执行查找之前展开,然后对 "agency" 字段执行最终查找。
但是,当我从该查询中获得结果时,我得到的文档数等于角色数。例如,我正在聚合的项目有 3 个角色和 1 个代理。因此,我返回了一个包含 3 个对象的数组,每个对象对应一个对象,而不是包含所有三个角色的角色数组的单个文档。代理数组也有可能有多个值。
迷路了...
您不必在 $lookup 之前 运行 $unwind
。 localField
部分指出:
If your localField is an array, you may want to add an $unwind stage to your pipeline. Otherwise, the equality condition between the localField and foreignField is foreignField: { $in: [ localField.elem1, localField.elem2, ... ] }
所以基本上如果你不 运行 $unwind
例如 roles
那么你将得到一个 roles
的数组作为 ObjectIds
替换为第二个集合中的对象数组。
因此您可以尝试以下聚合:
db.collection('projects').aggregate([
{
$match: {
agents: ObjectId(agent)
}
},
{
$lookup: {
from: "agents",
localField: "agents",
foreignField: "_id",
as: "agents"
}
},
{
$lookup: {
from: "roles",
localField: "roles",
foreignField: "_id",
as: "roles"
}
},
{
$lookup: {
from: "agencies",
localField: "agency",
foreignField: "_id",
as: "agency"
}
}
])
我无法尝试合并我的文档结果。这是我的查询和数据
{"_id":"5c21ab13d03013b384f0de26",
"roles":["5c21ab31d497a61195ce224c","5c21ab4ad497a6f348ce224d","5c21ab5cd497a644b6ce224e"],
"agency":"5b4ab7afd6ca361cb38d6a60","agents":["5b4ab5e897b24f1c4c8e3de3"]}
这里是查询
return db.collection('projects').aggregate([
{
$match: {
agents: ObjectId(agent)
}
},
{
$unwind: "$agents"
},
{
$lookup: {
from: "agents",
localField: "agents",
foreignField: "_id",
as: "agents"
}
},
{
$unwind: {
path: "$roles",
preserveNullAndEmptyArrays: true
}
},
{
$lookup: {
from: "roles",
localField: "roles",
foreignField: "_id",
as: "roles"
}
},
{
$lookup: {
from: "agencies",
localField: "agency",
foreignField: "_id",
as: "agency"
}
}
])
如您所见,项目集合中的一个条目有两个数组,在对每个条目执行查找之前展开,然后对 "agency" 字段执行最终查找。
但是,当我从该查询中获得结果时,我得到的文档数等于角色数。例如,我正在聚合的项目有 3 个角色和 1 个代理。因此,我返回了一个包含 3 个对象的数组,每个对象对应一个对象,而不是包含所有三个角色的角色数组的单个文档。代理数组也有可能有多个值。
迷路了...
您不必在 $lookup 之前 运行 $unwind
。 localField
部分指出:
If your localField is an array, you may want to add an $unwind stage to your pipeline. Otherwise, the equality condition between the localField and foreignField is foreignField: { $in: [ localField.elem1, localField.elem2, ... ] }
所以基本上如果你不 运行 $unwind
例如 roles
那么你将得到一个 roles
的数组作为 ObjectIds
替换为第二个集合中的对象数组。
因此您可以尝试以下聚合:
db.collection('projects').aggregate([
{
$match: {
agents: ObjectId(agent)
}
},
{
$lookup: {
from: "agents",
localField: "agents",
foreignField: "_id",
as: "agents"
}
},
{
$lookup: {
from: "roles",
localField: "roles",
foreignField: "_id",
as: "roles"
}
},
{
$lookup: {
from: "agencies",
localField: "agency",
foreignField: "_id",
as: "agency"
}
}
])