温馨提示:本文翻译自stackoverflow.com,查看原文请点击:reflection - Reflect on Gremlin traversal type (Edge, Vertex, Property) in CHOOSE step, possible?
graph-databases gremlin reflection sparql tinkerpop3

reflection - 在选择步骤中考虑Gremlin遍历类型(边,顶点,属性),可能吗?

发布于 2020-04-22 09:28:20

我正在扩展sparql-to-gremlin代码,以支持完全和部分未绑定的谓词查询,这些查询可被自动化流程用来探究图形结构。这样的想法是,您可以只连接到某个图形数据库,并提出一个具有一定限制的完全未绑定查询,并获得顶点属性,边线类型,边线属性等。然后可以进一步进行探讨。

现在,我可以解决一个完全未绑定的查询,并且可以解决将主题绑定到一个顶点的查询。现在,我想将其组合成一个多语言查询,并发现Gremlin MATCH步骤需要先对遍历的类型进行反思,然后才能决定实际应用哪些步骤。例如,如果遍历产生一个顶点,则要求出入/入出边缘和属性是有意义的;如果是Edge,则要求出入边没有意义,实际上会导致引发意外类型的错误。

因此,问题是,是否有可能编写一种“ switch”语句来反映该类型,然后仅询问在该上下文中有意义的事情?

这是我尝试支持的一种SPARQL查询(基于此处描述的众神之图https://old-docs.janusgraph.org/0.1.0/getting-started.html):

https://old-docs.janusgraph.org/0.1.0/images/graph-of-the-gods-2.png

SELECT ?BATTLE ?PRED ?VALUE
WHERE {
    vid:6 ep:battled ?BATTLE .
    ?BATTLE ?PRED ?VALUE .
}

在这里,我们从ID为6的顶点开始,使用带有“战斗”标签的输出边缘参考,然后获取边缘的所有可能属性及其值。

此处ID为6的顶点是Hercules,它具有3个向外标记为“战斗”的边缘,分别指向ID 9(尼美亚),10(Hydra)和11(Cerberus)的顶点。我想将?PRED绑定到v:id(边缘id),v:label(边缘标签),v:time(边缘时间属性值),v:place(边缘位置属性值),eps:战斗(将边与IN顶点相关的sparql-to-gremlin的扩展)。

查看更多

提问者
anton
被浏览
34
stephen mallette 2020-02-06 23:21

我认为我已解决了您的问题,但我认为我没有一个很好的答案。目前,Gremlin在类型检测方面还不是很好,并且该问题在TINKERPOP-2234上仍然存在对于大多数人来说,当他们在流中包含一组混合元素时,通常的解决方法是使用类似的步骤coalesce()choose()充当switch语句的形式,然后找出一些无法识别对象类型的过滤器。因此,我得出了一些混合的结果:

gremlin> g.V().union(outE(),__.in())
==>e[9][1-created->3]
==>e[7][1-knows->2]
==>e[8][1-knows->4]
==>v[1]
==>v[1]
==>v[4]
==>v[6]
==>e[10][4-created->5]
==>e[11][4-created->3]
==>v[1]
==>v[4]
==>e[12][6-created->3]

然后使用hasLabel()测试我知道仅属于顶点的标签,然后其他所有内容都必须是边:

gremlin> g.V().union(outE(),__.in()).choose(hasLabel('person','software'), values('name'), values('weight'))
==>0.4
==>0.5
==>1.0
==>marko
==>marko
==>josh
==>peter
==>1.0
==>0.4
==>marko
==>josh
==>0.2

显然不是很理想,但是通常可以解决大多数人的问题。希望我们能看到TINKERPOP-2234解决了3.5.0。

另一个可能的解决方法是使用一个lambda,该lambda在某些用例中效果很好,尽管我们尽力避免使用它们:

gremlin> g.V().union(outE(),__.in()).choose(filter{it.get() instanceof Vertex}, values('name'), values('weight'))
==>0.4
==>0.5
==>1.0
==>marko
==>marko
==>josh
==>peter
==>1.0
==>0.4
==>marko
==>josh
==>0.2