在 mongodb 中与查找的外部字段分组
group with lookup's foreign field in mongodb
我有两个不同的模型:
- 促销活动
- 标签
每个促销活动都有一个引用标签 ID 的字段。这是在我的模式中引用的并且工作正常:
const PromotionSchema = mongoose.Schema({
tags: { type: mongoose.Schema.Types.ObjectId, ref: 'Tag' }
}, { collection: 'promotions' });
我的问题是如何创建自定义响应以按标签对所有促销进行分组?像这样:
{
"tag": {
"_id": "999",
"value": "Lorem Ipsum"
},
"promotions": [{
"_id": "0001",
"value": "Value of promotion Nº1"
},
{
"_id": "0002",
"value": "Value of promotion Nº2"
},
... And the others that have the same Tag ID assigned
]}
}
现在,我正在使用 Vanilla Javascript 获取所有促销和过滤。我需要知道如何使用 Mongoose 改进它。
您可以尝试下面的聚合函数来实现结果...
如果你有 mongodb 版本 3.6
db.promotion.aggregate([
// stage 1
{ "$lookup": {
"from": Promotions.collection.name,
"let": { "tags": "$tags" },
"pipeline": [
{ "$match": { "$expr": { "$eq": [ "$_id", "$$tags" ] } } }
],
"as": "tags"
}},
// stage 2
{ "$addFields": {
"tags": { "$arrayElemAt": [ "$tags", 0 ] }
}},
// stage 3
{ "$group": {
"_id": "$tags._id",
"promotions": {
"$push": {
"fieldName1": "$fieldName1",
"fieldName2": "$fieldName2",
}
}
}}
])
如果您的 mongodb 版本早于 3.6
db.promotion.aggregate([
{ "$lookup": {
"from": Promotions.collection.name,
"localField": "tags",
"foreignField": "_id"
"as": "tags"
}},
{ "$unwind": "tags" },
{ "$group": {
"_id": "$tags._id",
"promotions": {
"$push": {
"fieldName1": "$fieldName1",
"fieldName2": "$fieldName2",
}
}
}}
])
两者都会给出类似的输出
{
"tag": {
"_id": "999",
"value": "Lorem Ipsum"
},
"promotions": [{
"_id": "0001",
"value": "Value of promotion Nº1"
},
{
"_id": "0002",
"value": "Value of promotion Nº2"
}
]}
}
我有两个不同的模型:
- 促销活动
- 标签
每个促销活动都有一个引用标签 ID 的字段。这是在我的模式中引用的并且工作正常:
const PromotionSchema = mongoose.Schema({
tags: { type: mongoose.Schema.Types.ObjectId, ref: 'Tag' }
}, { collection: 'promotions' });
我的问题是如何创建自定义响应以按标签对所有促销进行分组?像这样:
{
"tag": {
"_id": "999",
"value": "Lorem Ipsum"
},
"promotions": [{
"_id": "0001",
"value": "Value of promotion Nº1"
},
{
"_id": "0002",
"value": "Value of promotion Nº2"
},
... And the others that have the same Tag ID assigned
]}
}
现在,我正在使用 Vanilla Javascript 获取所有促销和过滤。我需要知道如何使用 Mongoose 改进它。
您可以尝试下面的聚合函数来实现结果...
如果你有 mongodb 版本 3.6
db.promotion.aggregate([
// stage 1
{ "$lookup": {
"from": Promotions.collection.name,
"let": { "tags": "$tags" },
"pipeline": [
{ "$match": { "$expr": { "$eq": [ "$_id", "$$tags" ] } } }
],
"as": "tags"
}},
// stage 2
{ "$addFields": {
"tags": { "$arrayElemAt": [ "$tags", 0 ] }
}},
// stage 3
{ "$group": {
"_id": "$tags._id",
"promotions": {
"$push": {
"fieldName1": "$fieldName1",
"fieldName2": "$fieldName2",
}
}
}}
])
如果您的 mongodb 版本早于 3.6
db.promotion.aggregate([
{ "$lookup": {
"from": Promotions.collection.name,
"localField": "tags",
"foreignField": "_id"
"as": "tags"
}},
{ "$unwind": "tags" },
{ "$group": {
"_id": "$tags._id",
"promotions": {
"$push": {
"fieldName1": "$fieldName1",
"fieldName2": "$fieldName2",
}
}
}}
])
两者都会给出类似的输出
{
"tag": {
"_id": "999",
"value": "Lorem Ipsum"
},
"promotions": [{
"_id": "0001",
"value": "Value of promotion Nº1"
},
{
"_id": "0002",
"value": "Value of promotion Nº2"
}
]}
}