在 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"
   }
   ]}
}