阿一小猿
1
我的数据中的数据结构如下:
tags:
person(phone, xm, ...)
edges:
record(start_time, ...)
其中:
-
person
的 id
取的是 phone
;
-
record
的 src
,dst
也是 phone
, rank
取的是 start_time
的时间戳;
- 两个点之间可能有几百上千条边;
我的需求:
- 我现在使用
find shortest path
语句查询两点之间的最短路径,但是因为两个点之间有很多条边,返回的结果很多记录中间节点都是重复的;
- 我的需求是只关注中间节点,如果中间节点一样就取其中一条,或者调用聚合函数对边进行聚合操作;
我现在的 ngql 如下:
只是取了 path 路径的所有的,该如何聚合操作呢?
FIND SHORTEST PATH FROM <vid1> TO <vid2> OVER * BIDIRECT YIELD PATH AS p |
YIELD NODES($-.p) AS vnodes;
阿一小猿
2
或者还有什么方法可以在数据库中全库搜索最短路径的方法?
问下,这种情况下,你期望结果是啥?
# 查找所有从 player100 到 team204 无环路径。
nebula> FIND NOLOOP PATH FROM "player100" TO "team204" OVER * YIELD path AS p;
+--------------------------------------------------------------------------------------------------------+
| p |
+--------------------------------------------------------------------------------------------------------+
| <("player100")-[:serve@0 {}]->("team204")> |
| <("player100")-[:follow@0 {}]->("player125")-[:serve@0 {}]->("team204")> |
| <("player100")-[:follow@0 {}]->("player101")-[:serve@0 {}]->("team204")> |
| <("player100")-[:follow@0 {}]->("player101")-[:follow@0 {}]->("player125")-[:serve@0 {}]->("team204")> |
| <("player100")-[:follow@0 {}]->("player101")-[:follow@0 {}]->("player102")-[:serve@0 {}]->("team204")> |
| ... |
+--------------------------------------------------------------------------------------------------------+
阿一小猿
4
您说的这种情况中间点没有重复的,下面我加了两条路径
增加路径之后的结果
# 查找所有从 player100 到 team204 无环路径。
nebula> FIND NOLOOP PATH FROM "player100" TO "team204" OVER * YIELD path AS p;
+--------------------------------------------------------------------------------------------------------+
| p |
+--------------------------------------------------------------------------------------------------------+
| <("player100")-[:serve@0 {}]->("team204")> |
| <("player100")-[:follow@0 {}]->("player125")-[:serve@0 {}]->("team204")> |
| <("player100")-[:follow@0 {}]->("player101")-[:serve@0 {}]->("team204")> |
| <("player100")-[:follow@0 {}]->("player101")-[:follow@0 {}]->("player125")-[:serve@0 {}]->("team204")> |
| <("player100")-[:follow@1 {}]->("player101")-[:follow@1 {}]->("player125")-[:serve@1 {}]->("team204")> |
| <("player100")-[:follow@0 {}]->("player101")-[:follow@0 {}]->("player102")-[:serve@0 {}]->("team204")> |
| <("player100")-[:follow@1 {}]->("player101")-[:follow@1 {}]->("player102")-[:serve@1 {}]->("team204")> |
| ... |
+--------------------------------------------------------------------------------------------------------+
我需要的结果: 意思就是,将中间节点一样的路径看作是重复的路径,就保留其中一条
# 查找所有从 player100 到 team204 无环路径。
nebula> FIND NOLOOP PATH FROM "player100" TO "team204" OVER * YIELD path AS p;
+--------------------------------------------------------------------------------------------------------+
| p |
+--------------------------------------------------------------------------------------------------------+
| <("player100")-[:serve@0 {}]->("team204")> |
| <("player100")-[:follow@0 {}]->("player125")-[:serve@0 {}]->("team204")> |
| <("player100")-[:follow@0 {}]->("player101")-[:serve@0 {}]->("team204")> |
| <("player100")-[:follow@0 {}]->("player101")-[:follow@0 {}]->("player125")-[:serve@0 {}]->("team204")> |
| <("player100")-[:follow@0 {}]->("player101")-[:follow@0 {}]->("player102")-[:serve@0 {}]->("team204")> |
| ... |
+--------------------------------------------------------------------------------------------------------+
FIND all PATH FROM "player100" TO "team204" OVER * YIELD distinct path AS p;
你加个 distinct 试试
阿一小猿
7
可不可以支持一下 呢?检索双向最短路径的时候,可以设置是否只遍历两个点之间的一条边;不然的话如果两条边之间有100条边,最后返回的结果量级就要乘以100,而且如果都遍历的话还特别耗时,感谢。
这里的问题是,你想要的是路径还是边。如果是路径的话,一条边标识的是一条路径。
find all/noloop path的目标就是要找到所有路径。因为后续可能还有根据边上的权重做排序等操作;
另外,你只是要最短路径吗?最短路径用 shortest path 就可以了吧?
阿一小猿
10
是的,我就是用的 find shortest path
,返回的结果还有很多中间节点一样但是边的rank值不一样的(这些对我来说算是重复路径),我需要的是忽略rank,只要两个点之间有一个边被遍历过,就忽略这两个点之间的其他边了
阿一小猿
12
这个很简单,最短路径是一跳,如果是两跳,最后的结果的量级就要相乘了
你可以用 match 里的 shortestpath
后面 3.7 发布以后,find path 里有 single shortest ptah 也是一样的。
阿一小猿
16
我测试了一下 使用 match检索最短路径时有一个问题:
- 就是他只会返回一条路径,如果这两个点之间还可以通过其他点连通,就无法把两条路径都返回
比如说:
假设 a 到 e,有一下两条最短路径,他就只会返回其中一条,无法全部返回
a->b->c->d->e
a->f->c->d->e
然说可以忽略 rank 值,但是会漏了中间节点不同的路径,所以会遗漏一些信息,这种需求能不能实现呢?感谢
system
关闭
17
此话题已在最后回复的 30 天后被自动关闭。不再允许新回复。