我有四个不同的系列。从哪三个连成一个:
Collection_A = {
_id: 1
name: A
includes: [
{
_id: 1,
includes_id: 222,
},
{
_id: 2,
includes_id: 333
}
]
}
Collection_B = {
_id: 222,
type: Computer,
name: Computer,
ref_id: 1
}
Collection_C = {
_id: 333,
type: Human,
name: Human,
ref_id: 1
}
Collection_D = {
_id: 444,
type: Animal,
name: Animal,
ref_id: 1
}
所以集合 A 可以在包含对象中包含集合 B、C 和 D。它包括至少一个集合。
所以在集合A的includes对象中是includes_id,它是集合B、C和D中的_id。 集合 A 中的 _id 是集合 B、C 和 D 中的 ref_id。
我现在的问题是,该聚合只需要最后一个映射的集合。
我现在的代码如下:
Collection_A.aggregate([
{
$lookup: {
from: "collectionb",
localField: "includes.includes_id",
foreignField: "_id",
as: "colb",
},
},
{
$lookup: {
from: "collectionc",
localField: "includes.includes_id",
foreignField: "_id",
as: "colc",
},
},
{
$project: {
_id: 1,
status: 1,
type: 1,
includes_list: {
$map: {
input: "$includes",
as: "i",
in: {
$arrayElemAt: [
{
$filter: {
input: "$colb",
cond: {
$eq: ["$$this._id", "$$i.includes_id"],
},
},
},
0,
],
$arrayElemAt: [
{
$filter: {
input: "$colc",
cond: {
$eq: ["$$this._id", "$$i.includes_id"],
},
},
},
0,
],
},
},
},
},
},
]);
我试图在每次查找时都使 $lookup 相同,但它只使用最后一次查找的数据,而其他数据显示为空。 所以我将 $lookup 设置为唯一的,并在 map 中放入了两个 in,但也显示了最后查找的数据,而其他的则为 null。
当我做这样的映射时:
includes_list: {
$map: {
input: "$icludes",
as: "i",
in: {
{
Col_A : {
$arrayElemAt: [
{
$filter: {
input: "$A",
cond: {
$eq: ["$$this._id", "$$i.includes"],
},
},
},
0,
],
},
Col_B : {
$arrayElemAt: [
{
$filter: {
input: "$B",
cond: {
$eq: ["$$this._id", "$$i.includes"],
},
},
},
0,
],
}
}
},
},
}
它有效。但没有正确的输出,因为我需要在一个数组中包含 includes_list。
我想要的输出如下:
{
includes: [
{
_id: 1,
name: Computer,
includes_list: [
{
_id: 222,
type: Computer,
name: Computer,
ref_id: 1
},
{
_id: 333,
type: Human,
name: Human,
ref_id: 1
},
]
},
{
_id: 2,
name: Animal,
includes_list: [
{
_id: 333,
type: Human,
name: Human,
ref_id: 2
},
]
}
]
}
非常感谢您的帮助!
答案 0 :(得分:0)
对于这种情况,
$facet
帮助对传入数据进行分类
db.Collection_A.aggregate([
{ $unwind: "$includes },
{
"$facet": {
"joinB": [
{
"$lookup": {
"from": "Collection_B", "localField": "includes.includes_id",
"foreignField": "_id", "as": "includes.includes_list"
}
},
{
"$group": {
"_id": "$_id",
"name": { "$first": "$name" },
includes: { $push: "$includes" }
}
}
],
"joinC": [
{
"$lookup": {
"from": "Collection_C", "localField": "includes.includes_id",
"foreignField": "_id", "as": "includes.includes_list"
}
},
{
"$group": {
"_id": "$_id",
"name": { "$first": "$name" },
includes: { $push: "$includes" }
}
}
],
"joinD": [
{
"$lookup": {
"from": "Collection_D", "localField": "includes.includes_id",
"foreignField": "_id", "as": "includes.includes_list"
}
},
{
"$group": {
"_id": "$_id",
"name": { "$first": "$name" },
includes: { $push: "$includes" }
}
}
],
}
},
{
$project: {
combined: {
"$concatArrays": [ "$joinB", "$joinC", "$joinD" ]
}
}
},
{ "$unwind": "$combined" },
{
"$replaceRoot": { "newRoot": "$combined" }
},
{
"$project": {
_id: 1,
name: 1,
includes: {
$filter: {
input: "$includes",
cond: {
$ne: [ "$$this.includes_list",[] ]
}
}
}
}
}
])
注意:我觉得这是你遵循的一种反模式。如果你在项目的早期阶段,如果我没记错的话最好改变结构。