Mongodb 聚合管道项目

Mongodb aggregation pipeline project

大家好,

我需要一些帮助来使聚合管道正常工作,我一直试图让它工作一段时间但只完成了一半。 这是我的设置

用户文档如下:

{
    "_id": { "$oid": "5fea4f976ca46d93c010d33d" },
    .....................
    "firstname": "firstname1",
    "lastname": "lastname1",
    "key1": "value1",
    "key2": "value2",
    "key3": "value3",
    "key4": "value4",
    ..................
    "certifications": {
        certs: [
            {
                "_id": "5fea44b96ca46d93c010d330",
                "itemID": 1,
                "date_certified": "2011-05-30 05:09:48"
            },
            {
                "_id": "5fea44b96ca46d93c010d334",
                "itemID": 3,
                "date_certified": "2007-01-30 06:01:51"
            },
            {
                "_id": "5fea44b96ca46d93c010d337",
                "itemID": 5,
                "date_certified": "2007-09-21 16:52:52"
            }
        ]
    },
    .......................
    ...................
    .....................
},

{
    "_id": { "$oid": "5fea4f976ca46d93c010545453" },
    .....................
    .....................
    "firstname": "firstname2",
    "lastname": "lastname2",
    "key1": "value1",
    "key2": "value2",
    "key3": "value3",
    "key4": "value4",
    ..................
    "certifications": {
        certs: [
            {
                "_id": "5fea44b96ca46d93c010d330",
                "itemID": 2,
                "date_certified": "2011-05-30 05:09:48"
            },
            {
                "_id": "5fea44b96ca46d93c010d334",
                "itemID": 4,
                "date_certified": "2007-01-30 06:01:51"
            }
        ]
    },
    .......................
    ...................
    .....................
}

证书 文档是后续

[{
  "_id": {
    "$oid": "5fea44b96ca46d93c010d32e"
  },
  "itemID": 1,
  "acronym": "acro1",
  "country": "my Great Country",
  "name": {
    "key1": "My Key 1 description",
    "key2": "My Key 2 description",
    "key3": "My Key 3 description",
    "key4": "My Key 4 description"
  },
  "website": "www.myGreatWebsite.com"
},

{
  "_id": {
    "$oid": "5fea44b96ca46d93c010d32f"
  },
  "itemID": 2,
  "acronym": "acro2",
  "country": "my Great Country",
  "name": {
    "key1": "My Key 1 description",
    "key2": "My Key 2 description",
    "key3": "My Key 3 description",
    "key4": "My Key 4 description"
  },
  "website": "www.myGreatWebsite.com"
},

{
  "_id": {
    "$oid": "5fea44b96ca46d93c010d330"
  },
  "itemID": 3,
  "country": "my Great Country",
  "name": {
    "key1": "My Key 1 description",
    "key2": "My Key 2 description",
    "key3": "My Key 3 description",
    "key4": "My Key 4 description"
  },
  "website": "www.myGreatWebsite.com"
},

{
  "_id": {
    "$oid": "5fea44b96ca46d93c010d331"
  },
  "itemID": 4,
  "country": "my Great Country",
  "name": {
    "key1": "My Key 1 description",
    "key2": "My Key 2 description",
    "key3": "My Key 3 description",
    "key4": "My Key 4 description"
  },
  "website": "www.myGreatWebsite.com"
},

{
  "_id": {
    "$oid": "5fea44b96ca46d93c010d332"
  },
  "itemID": 5,
  "country": "my Great Country",
  "name": {
    "key1": "My Key 1 description",
    "key2": "My Key 2 description",
    "key3": "My Key 3 description",
    "key4": "My Key 4 description"
  },
  "website": "www.myGreatWebsite.com"
}]

现在我的集合

db.users.aggregate([
  {
    '$lookup': {
      'from': 'certifications', 
      'let': {
        'certs': '$certifications.certs'
      }, 
      'pipeline': [
        {
          '$match': {
            '$expr': {
              '$in': [
                '$itemID', '$$certs.itemID'
              ]
            }
          }
        }, {
          '$project': {
            '_id': 0, 
            'itemID': '$itemID', 
            'description': '$name.key1', 
            'acronyme': '$acronym', 
            'country': '$country', 
            'count': {
              '$size': '$$certs'
            }, 
            'date_cert': '$$certs.date_certified'
          }
        }
      ], 
      'as': 'certifications'
    }
  }
])

结果是

{
  .........
  ...........
  "firstname": "firstname1",
  "lastname": "lastname1",
  "key1": "value1",
  "key2": "value2",
  "key3": "value3",
  "key4": "value4",
  ..................
  certification: {
    certs: [
      {
        itemID: 1,
        country: 'my Great Country',
        description: 'My Key 1 description',
        count: 1,
        date_cert: [
          0:"2005-01-06 10:48:16"
        ]
      },
    ]
  }
  ........
  .........
},

{
  .........
  ...........
  "firstname": "firstname2",
  "lastname": "lastname2",
  "key1": "value1",
  "key2": "value2",
  "key3": "value3",
  "key4": "value4",
  ..................
  certification: {
    certs: [
      {
        itemID: 2,
        country: 'my Great Country',
        description: 'My Key 2 description',
        count: 2,
        date_cert: [
          "2005-01-06 10:48:16"
          "2014-06-21 22:44:56"
        ]
      },
      {
        itemID: 4,
        country: 'my Great Country',
        description: 'My Key 4 description',
        count: 2,
        date_cert: [
          "2005-01-06 10:48:16"
          "2014-06-21 22:44:56"
        ]
      }
    ]
  }
  ........
  .........
}

但预期结果是

{
  .........
  ...........
  "firstname": "firstname1",
  "lastname": "lastname1",
  "key1": "value1",
  "key2": "value2",
  "key3": "value3",
  "key4": "value4",
  ..................
  certification: {
    certs: [
      {
        itemID: 1,
        country: 'my Great Country',
        description: 'My Key 1 description',
        date_cert: "2005-01-06 10:48:16"
      },
    ],
    count: 1,
  }
  ........
  .........
},

{
  .........
  ...........
  "firstname": "firstname2",
  "lastname": "lastname2",
  "key1": "value1",
  "key2": "value2",
  "key3": "value3",
  "key4": "value4",
  ..................
  certification: {
    certs: [
      {
        itemID: 2,
        country: 'my Great Country',
        description: 'My Key 2 description',
        date_cert: "2005-01-06 10:48:16"
      },
      {
        itemID: 4,
        country: 'my Great Country'
        description: 'My Key 4 description',
        date_cert: "2014-06-21 22:44:56"
      }
    ],
    count: 2
  }
  ........
  .........
}

基本上我希望将管道匹配阶段的结果与认证查找的文档合并,以便我可以同时使用两者。 在制定聚合时,我们将不胜感激。

谢谢

  • $unwind解构certs数组
  • $lookup with certificationscertifications.certs.itemID 作为 localField 传递,将 itemID 作为 foreignField 传递,结果作为 certification
  • $unwind 从查找和 certification
  • 中解构结果
  • $group by _id 并重建 certs 数组并在合并后使用 $mergeObjects 推送所需字段,使用 $sum[=57= 获取计数]
db.users.aggregate([
  { $unwind: "$certifications.certs" },
  {
    $lookup: {
      from: "certifications",
      localField: "certifications.certs.itemID",
      foreignField: "itemID",
      as: "certification"
    }
  },
  { $unwind: "$certification" },
  {
    $group: {
      _id: "$_id",
      certs: {
        $push: {
          $mergeObjects: [
            "$certifications.certs",
            {
              country: "$certification.country",
              description: "$certification.name.key1"
            }
          ]
        }
      },
      count: { $sum: 1 }
    }
  }
])

Playground


没有 $unwind 和 $group 的第二种方法,这可能会导致性能和速度问题,

  • $lookupcertifications 集合
  • $map 迭代 certifications.certs 数组
  • 的循环
  • $reduce 迭代 certification 的循环,检查 itemID 的条件,它将 return 特定字段,
  • 返回 $map,使用 $mergeObjects
  • 合并当前对象和来自 $reduce 的 return 对象
  • 使用 $size`
  • 获取 certs 的计数
db.users.aggregate([
  {
    $lookup: {
      from: "certifications",
      localField: "certifications.certs.itemID",
      foreignField: "itemID",
      as: "certification"
    }
  },
  {
    $addFields: {
      "certification": "$$REMOVE",
      "certifications.certs": {
        $map: {
          input: "$certifications.certs",
          as: "c",
          in: {
            $mergeObjects: [
              "$$c",
              {
                $reduce: {
                  input: "$certification",
                  initialValue: {},
                  in: {
                    $cond: [
                      { $eq: ["$$this.itemID", "$$c.itemID"] },
                      {
                        country: "$$this.country",
                        description: "$$this.name.key1"
                      },
                      "$$value"
                    ]
                  }
                }
              }
            ]
          }
        }
      },
      "certifications.count": { $size: "$certifications.certs" }
    }
  }
])

Playground