【问题标题】:How to aggregate entities into group based on edge data?如何根据边缘数据将实体聚合成组?
【发布时间】:2021-07-20 07:27:04
【问题描述】:

我有大量存储在 mongodb 中的无向边,需要聚合成组。

示例文档:

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

例如

  • a - b
  • a - d
  • b - c
  • f - e
  • g - h
  • h - 我

将产生 3 个组:

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

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

【问题讨论】:

  • 可以添加实际的文档结构吗?

标签: python-3.x mongodb aggregate


【解决方案1】:

首先让我说 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

【讨论】:

  • 这是一个很好的答案,也是解决方案之一。我知道 mongo 不是图形数据库,但数据存储在那里,这首先可能是一个错误。仅以编程方式完成所有这些操作而不是查询数据库是否有意义?
  • 我个人会用代码来做,是的,因为您可以创建自己的“BFS/BDS”逻辑并使这个过程更加精简(并且在 ent1ent2 字段上的索引可能有点高效),我给出“mongo-y”方式的原因是 1. 被问到的内容和 2. 展示 mongo 的多功能性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-01
  • 1970-01-01
  • 2023-03-09
  • 2013-08-26
  • 2021-12-04
  • 2022-01-11
  • 2016-11-05
相关资源
最近更新 更多