如何解决Gremlin 查询,用于获取“依赖图”之类的图的顺序
如下图:
g.addV("entity").property(id,"A")
.addV("entity").property(id,"B")
.addV("entity").property(id,"C")
.addV("entity").property(id,"D")
.addV("entity").property(id,"E")
.addV("entity").property(id,"F")
.addV("entity").property(id,"G")
.addV("entity").property(id,"H")
.addE("needs").from(g.V("A")).to(g.V("B"))
.addE("needs").from(g.V("A")).to(g.V("C"))
.addE("needs").from(g.V("A")).to(g.V("D"))
.addE("needs").from(g.V("A")).to(g.V("E"))
.addE("needs").from(g.V("C")).to(g.V("F"))
.addE("needs").from(g.V("D")).to(g.V("F"))
.addE("needs").from(g.V("E")).to(g.V("G"))
.addE("needs").from(g.V("F")).to(g.V("H"))
正确顺序的一种变体是
[[B,H,G],[F,E],[C,D],[A]]
或者只是
[B,G,F,E,C,D,A]
“组”内的顺序(例如 [B,G] 与 [H,B])并不重要。
如果这些节点位于依赖关系图中,我该如何检索正确的顺序来解析它们?
我对算法的想法将遵循以下两种解决方案之一:
A) 从叶子节点开始,遍历到父节点
- 检索所有叶顶点(无出边),附加到结果集,并放入
current
和resolved
。 - 循环遍历所有
current
并查看它们的所有子项(它们引用的顶点)是否都包含在resolved
中。如果是,则将当前顶点保存到resolved
并附加到结果集。将顶点的父项保存到current
中。 - 如果
current
有元素,转到 2,否则完成。
B) 简化从叶节点开始,但每次迭代都查看整个图
- 检索所有叶顶点(无出边),附加到结果集,并放入
resolved
。 - 查找所有未包含在
resolved
中且在resolved
中没有任何引用顶点的顶点。将这些附加到结果集。如果没有顶点,返回结果集,否则重复2。
这可能吗?如果是这样,如何?我可以在遍历时使用这些 current
和 resolved
集合吗?
解决方法
在大图中,这不太可能是一个有效的查询,但这里有一个解决方案。请注意,初始集合之后的列表与您的问题的顺序相反,因为这是遇到这些顶点的顺序。一种更有效的方法可能是反转“树”并从已知的根而不是“所有叶子”开始。
gremlin> g.V().where(__.not(out())).store('a').
......1> repeat(__.in()).emit().
......2> until(__.not(__.in())).
......3> dedup().
......4> union(cap('a'),identity()).
......5> fold()
==>[[v[A1],v[A4]],v[A0],v[A3],v[A2]]
更新
鉴于您的新数据集,我不得不采取不同的方法。我之前的查询使用广度优先搜索,但这不会产生您需要的排序。我改变了使用 index
步骤的方法,并且对于找到的每个顶点,只保留在路径中找到的具有最高索引值的顶点。结果列表就是您需要的列表,只是顺序相反。我们还可以添加到查询以反转列表 - 如下所示。
gremlin> g.V().where(__.not(out())).
......1> repeat(__.in()).
......2> until(__.not(__.in())).path().index().unfold().
......3> order().by(tail(local),desc).limit(local,1).dedup().fold()
==>[v[A],v[C],v[D],v[E],v[F],v[B],v[G],v[H]]
如果您想在查询中反转列表,您也可以这样做。
gremlin> g.V().where(__.not(out())).
......1> repeat(__.in()).
......2> until(__.not(__.in())).path().index().unfold().
......3> order().by(tail(local),1).dedup().fold().index().
......4> unfold().order().by(tail(local),1).fold()
==>[v[H],v[A]]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。