如何根据边缘数据将实体聚合到组中?
How to aggregate entities into group based on edge data?
我在 mongodb 中存储了大量无向边,需要将其聚合成组。
示例文档:
{
'_id': ObjectId('604065fe7e8146a4eeb7d7af'),
'ent1': `id_of_entity1`,
'ent2': `id_of_entity2`
}
例如
- a - b
- 一-d
- b - c
- f - e
- g - h
- h - i
会产生 3 个组:
- [a, b, c, d]
- [f, e]
- [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"
]
]
]
}
]
}
}
}
}
}
])
我在 mongodb 中存储了大量无向边,需要将其聚合成组。
示例文档:
{
'_id': ObjectId('604065fe7e8146a4eeb7d7af'),
'ent1': `id_of_entity1`,
'ent2': `id_of_entity2`
}
例如
- a - b
- 一-d
- b - c
- f - e
- g - h
- h - i
会产生 3 个组:
- [a, b, c, d]
- [f, e]
- [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"
]
]
]
}
]
}
}
}
}
}
])