如何根据边缘数据将实体聚合到组中?

How to aggregate entities into group based on edge data?

我在 mongodb 中存储了大量无向边,需要将其聚合成组。

示例文档:

{
  '_id': ObjectId('604065fe7e8146a4eeb7d7af'),
  'ent1': `id_of_entity1`,
  'ent2': `id_of_entity2`
}

例如

会产生 3 个组:

  1. [a, b, c, d]
  2. [f, e]
  3. [g, h, i]

执行此操作的有效方法是什么?

首先让我说 Mongo 不是图形数据库。这通常意味着它不会是我解决任何图形相关问题的首选。

您所要求的可以在 Mongo 中完成,但绝对效率不高,因为它需要您多次遍历整个集合。我将附上代码示例,以防您确实想使用它,但我再次建议您重新考虑 db 选择、数据结构选择或您可以做的任何更改以使其更易于使用。

话虽如此,这里是代码,方法是首先 $group 整个集合,以便我们可以对其进行迭代。然后通过查看数组交集是否不为 0,开始将文档聚类成组。

db.collection.aggregate([
  {
    $group: {
      _id: null,
      ents: {
        $push: "$$ROOT"
      }
    }
  },
  {
    $project: {
      clusters: {
        $reduce: {
          input: "$ents",
          initialValue: [],
          in: {
            $cond: [
              {
                $gt: [
                  {
                    $size: {
                      $filter: {
                        input: "$$value",
                        as: "val",
                        cond: {
                          $gt: [
                            {
                              $size: {
                                "$setIntersection": [
                                  "$$val",
                                  [
                                    "$$this.ent1",
                                    "$$this.ent2"
                                  ]
                                ]
                              }
                            },
                            0
                          ]
                        }
                      }
                    }
                  },
                  0
                ]
              },
              {
                $map: {
                  input: "$$value",
                  as: "val",
                  in: {
                    $cond: [
                      {
                        $gt: [
                          {
                            $size: {
                              "$setIntersection": [
                                "$$val",
                                [
                                  "$$this.ent1",
                                  "$$this.ent2"
                                ]
                              ]
                            }
                          },
                          0
                        ]
                      },
                      {
                        "$setUnion": [
                          "$$val",
                          [
                            "$$this.ent1",
                            "$$this.ent2"
                          ]
                        ]
                      },
                      "$$val"
                    ]
                  }
                }
              },
              {
                "$concatArrays": [
                  "$$value",
                  [
                    [
                      "$$this.ent1",
                      "$$this.ent2"
                    ]
                  ]
                ]
              }
            ]
          }
        }
      }
    }
  }
])

Mongo Playground