【问题标题】:Referring to a different collection from an existing one and counting from the same collection引用与现有集合不同的集合并从同一集合计数
【发布时间】:2020-10-29 05:37:55
【问题描述】:

我必须收集 A 和 B,其中 A 的文档包含对象 ID,这些对象 ID 存在于字段中心和 gcentre 的 B 中。我目前正在输出包含父中心名称的结果,方法是从集合 A 的对象 id 引用到 B,然后引用 gcentre 的 id 来查找子中心和中心,并计算通过 javascript 后处理分配的文档。刚接触聚合管道,我不知道如何通过对象 id 和那种记录计数来引用。聚合管道可以吗?我已经尝试使用 $lookup,但它似乎没有按预期提供输出。

集合 A 中的文档:

{
  "_id": {
        "$oid": "5bbafa98d8c77251bea30f8c"
    },
    "parentCentre": {
        "$oid": "1cbafa99d8c77251bea30f11"
    },
    "childCentre": {
        "$oid": "5cbafa99d8c77251bea30f8d"
    },
},
{
  "_id": {
        "$oid": "5bbafa98d8c77251bea30f8c"
    },
    "parentCentre": {
        "$oid": "1cbafa99d8c77251bea30f11"
    },
    "childCentre": {
        "$oid": "5cbafa99d8c77251bea30f8d"
    },
},
{
  "_id": {
        "$oid": "5bbafa98d8c77251bea30f8c"
    },
    "parentCentre": {
        "$oid": "1cbafa99d8c77251bea30f11"
    },
    "childCentre": {
        "$oid": "5cbafa99d8c77251bea30f8d"
    },
},
{
  "_id": {
        "$oid": "5bbafa98d8c77251bea30f8c"
    },
    "parentCentre": {
        "$oid": "1cbafa99d8c77251bea30f21"
    },
    "childCentre": {
        "$oid": "5cbafa99d8c77251bea30f6d"
    },
}

集合 B 中的文档:

   {
        "_id": {
                "$oid": "1cbafa99d8c77251bea30f11"
            },
            "Type": "Parent",
            "Name": "Kris Labs"
        },
    {
        "_id": {
                "$oid": "1cbafa99d8c77251bea30f21"
            },
            "Type": "Parent",
            "Name": "DEX Labs"
        },
    {
        "_id": {
                "$oid": "5cbafa99d8c77251bea30f8d"
            },
            "Type": "Child",
            "Name": "Mili Labs"
        },
        {
        "_id": {
                "$oid": "5cbafa99d8c77251bea30f6d"
            },
            "Type": "Child",
            "Name": "Max Labs"
        }

结果:

{
  "parentCentreName":"Kris Labs",
  "Records":{
            {
            childCentreName: "Max Labs",
            recordCount: 3
              }
             }
},
{
  "parentCentreName":"DEX Labs",
  "Records":{
            {
            childCentreName: "Mili Labs",
            recordCount: 1
              }
             }
}

【问题讨论】:

    标签: mongodb aggregation-framework aggregate


    【解决方案1】:

    您可以使用以下聚合查询:

    db.A.aggregate([
      {
        $group: {
          _id: {
            p: "$parentCentre",
            c: "$childCentre"
          },
          count: {
            $sum: 1
          }
        }
      },
      {
        $group: {
          _id: "$_id.p",
          Records: {
            $push: {
              childCentreName: "$_id.c",
              recordCount: "$count"
            }
          }
        }
      },
      {
        $unwind: "$Records"
      },
      {
        "$lookup": {
          "from": "B",
          "localField": "_id",
          "foreignField": "_id",
          "as": "p"
        }
      },
      {
        "$lookup": {
          "from": "B",
          "localField": "Records.childCentreName",
          "foreignField": "_id",
          "as": "c"
        }
      },
      {
        $unwind: "$c"
      },
      {
        $unwind: "$p"
      },
      {
        $project: {
          "parentCentreName": "$p.Name",
          "Records.childCentreName": "$c.Name",
          "Records.recordCount": 1,
          _id: 0
        }
      },
      {
        $group: {
          _id: "$parentCentreName",
          "Records": {
            $push: "$Records"
          }
        }
      },
      {
        $project: {
          "parentCentreName": "$_id",
          "Records": 1,
          _id: 0
        }
      }
    ])
    

    MongoDB Playground

    【讨论】:

    • 为什么我们在 $p 和 $c 上使用了 $unwind?
    • $p 和 $c 是 $lookup 的结果,它们作为数组返回。因此,我们使用 $unwind 将两个数组 $p、$c 展平,以便将文档转换为所需的输出格式
    • Tiya,假设如果我们将不同的子中心分配给一个父中心,那么这个管道实际上是在重复记录。
    • { "parentCentreName":"DEX Labs", "Records":{ { childCentreName: "Mili Labs", recordCount: 1 } } }, { "parentCentreName":"DEX Labs", "Records":{ { childCentreName: "Clown Labs", recordCount: 8 } } }, { "parentCentreName":"DEX Labs", "Records":{ { childCentreName: "Tera Labs", recordCount: 3 } } }
    • 你能否检查一下这个查询,处理多个儿童中心,mongoplayground.net/p/Ii2yE_sJY9v,如果这能解决问题,请告诉我。
    猜你喜欢
    • 2019-10-13
    • 1970-01-01
    • 2020-11-26
    • 2019-02-11
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 2014-04-30
    • 1970-01-01
    相关资源
    最近更新 更多