Gremlin查询是否有效取决于上下文 [英] Gremlin query works or not depending on the context
问题描述
在查询中(通过斯蒂芬·马莱特(Stephen Mallette)在
In a query (by the way written by stephen mallette in this question) the problem is that works in gremlify, but when I paste it in my project gives an incorrect output.
因此,我打开gremlify编写了一个数据创建查询,然后将其粘贴到gremlin控制台中,以便可以在那里进行测试,并且我发现如果在查询的数据创建部分之后执行了该代码,并且在gremlify中不起作用,据我了解,它应该可以工作.
So I opened gremlify to write a data creation query to then paste it in the gremlin console so I can test it there, and I noticed it doesn't work in gremlify if it's executed after the data creation part of the query and it should work as far as I understand.
查询是这样的:
g.V().as('a').
repeat(both().simplePath()).
times(2).
where(both().as('a')).
path().
map(unfold().limit(3).order().by(id).dedup().fold())
dedup().
group('m').
by(limit(local,2)).
group('m').
by(tail(local,2)).
group('m').
by(union(limit(local,1),tail(local,1)).fold()).
cap('m').
unfold().
map(select(values).unfold().unfold().order().by(id).dedup().fold()).
dedup().
map(unfold().values('name').fold())
在这里有效,输出正确: https://gremlify.com/psiygozr559
Here it works, output is correct: https://gremlify.com/psiygozr559
此处给出了错误的输出: https://gremlify.com/mqw6ut0y1z (相同的图形,但通过查询创建)
Here it gives an incorrect output: https://gremlify.com/mqw6ut0y1z (same graph but created with a query)
这里根本不提供任何输出: https://gremlify.com/fzgmzdq1omq (与以前相同,但第1行有所更改)
Here it does not give any output at all: https://gremlify.com/fzgmzdq1omq (same than before with a change in line 1)
在我的项目中也给出了不正确的输出,并且在执行查询之前,我没有执行任何奇怪的事情,就像上面的gremlify项目中一样.
In my project also gives an incorrect output and I'm not executing anything weird before the query like in the gremlify projects above.
还有另一个查询,它是我自己编写的,效率较低,但在所有相同情况下和我的项目中均能完美运行,请参阅:
There is another query that does the same, I wrote it myself, is less efficient but works perfectly in all the same situations and in my project, see:
https://gremlify.com/zihygx0w8e
https://gremlify.com/xsc6q8dranj
在我的项目中,我使用Node.js在未更改默认配置的情况下以本地方式连接到gremlin服务器.
In my project I'm connecting to gremlin server locally with with the default configuration untouched, using Node.js.
这里发生了我不理解的事情.
Something is happening here that I don't understand.
推荐答案
通过扩展遍历,您扩展了Path
.将addV('j')
放在遍历的前面会添加一些我的原始算法未考虑的内容:
By extending the traversal you've extended the Path
. Placing addV('j')
at the front of the traversal adds something my original algorithm did not take into account:
gremlin> g.addV("j").sideEffect(V().drop()).sideEffect(
......1> addV("user").property("name", "luana").as("luana")
......2> .addV("user").property("name", "luisa").as("luisa")
......3> .addV("user").property("name", "sabrina").as("sabrina")
......4> .addV("user").property("name", "marcello").as("marcello")
......5> .addV("user").property("name", "mario").as("mario")
......6> .addV("user").property("name", "lidia").as("lidia")
......7>
......7> .addE("friend").from("luana").to("luisa")
......8> .addE("friend").from("luana").to("sabrina")
......9> .addE("friend").from("luana").to("marcello")
.....10> .addE("friend").from("luana").to("mario")
.....11> .addE("friend").from("luana").to("lidia")
.....12>
.....12> .addE("friend").from("sabrina").to("luisa")
.....13> .addE("friend").from("sabrina").to("marcello")
.....14> .addE("friend").from("sabrina").to("mario")
.....15>
.....15> .addE("friend").from("mario").to("luisa")
.....16> .addE("friend").from("mario").to("marcello")
.....17> ).V().as('a').
.....18> repeat(both().simplePath()).
.....19> times(2).
.....20> where(both().as('a')).
.....21> path().by(label)
==>[j,user,user,user]
==>[j,user,user,user]
==>[j,user,user,user]
==>[j,user,user,user]
...
==>[j,user,user,user]
您可以通过以下方式解决此问题:命名您关心的路径,或者限制或过滤掉该初始路径元素:
You can account for that by naming the path you care about or otherwise limiting or filtering away that initial path element:
gremlin> g.addV("j").sideEffect(V().drop()).sideEffect(
......1> addV("user").property("name", "luana").as("luana")
......2> .addV("user").property("name", "luisa").as("luisa")
......3> .addV("user").property("name", "sabrina").as("sabrina")
......4> .addV("user").property("name", "marcello").as("marcello")
......5> .addV("user").property("name", "mario").as("mario")
......6> .addV("user").property("name", "lidia").as("lidia")
......7>
......7> .addE("friend").from("luana").to("luisa")
......8> .addE("friend").from("luana").to("sabrina")
......9> .addE("friend").from("luana").to("marcello")
.....10> .addE("friend").from("luana").to("mario")
.....11> .addE("friend").from("luana").to("lidia")
.....12>
.....12> .addE("friend").from("sabrina").to("luisa")
.....13> .addE("friend").from("sabrina").to("marcello")
.....14> .addE("friend").from("sabrina").to("mario")
.....15>
.....15> .addE("friend").from("mario").to("luisa")
.....16> .addE("friend").from("mario").to("marcello")
.....17> ).V().as('a').
.....18> repeat(both().simplePath()).
.....19> times(2).
.....20> where(both().as('a')).
.....21> path().from('a').
.....22> map(unfold().limit(3).order().by(id).dedup().fold()).
.....23> dedup().
.....24> group('m').
.....25> by(limit(local,2)).
.....26> group('m').
.....27> by(tail(local,2)).
.....28> group('m').
.....29> by(union(limit(local,1),tail(local,1)).fold()).
.....30> cap('m').
.....31> unfold().
.....32> map(select(values).unfold().unfold().order().by(id).dedup().fold()).
.....33> dedup().
.....34> map(unfold().values('name').fold())
==>[luana,luisa,sabrina,mario]
==>[luana,sabrina,marcello,mario]
==>[luana,luisa,sabrina,marcello,mario]
请注意上面的第21行,我们仅需添加path().from('a')
,即在步骤标签"a"处开始路径,然后该查询将再次开始工作.
Note line 21 above where we simply add path().from('a')
which says, start the path at the step label "a", and then the query starts working again.
关于另一个不使用sideEffect()
来添加示例图形数据的示例,请注意path()
遵循repeat()
时的输出:
Regarding your other example that doesn't use sideEffect()
to add the sample graph data, note the output of path()
when it follows repeat()
:
gremlin> g.addV("j").sideEffect(V().drop()).
......1> addV("user").property("name", "luana").as("luana").
......2> addV("user").property("name", "luisa").as("luisa").
......3> addV("user").property("name", "sabrina").as("sabrina").
......4> addV("user").property("name", "marcello").as("marcello").
......5> addV("user").property("name", "mario").as("mario").
......6> addV("user").property("name", "lidia").as("lidia").
......7>
......7> addE("friend").from("luana").to("luisa").
......8> addE("friend").from("luana").to("sabrina").
......9> addE("friend").from("luana").to("marcello").
.....10> addE("friend").from("luana").to("mario").
.....11> addE("friend").from("luana").to("lidia").
.....12>
.....12> addE("friend").from("sabrina").to("luisa").
.....13> addE("friend").from("sabrina").to("marcello").
.....14> addE("friend").from("sabrina").to("mario").
.....15>
.....15> addE("friend").from("mario").to("luisa").
.....16> addE("friend").from("mario").to("marcello").
.....17> V().as('a').both().path()
==>[v[712],v[713],v[715],v[717],v[719],v[721],v[723],e[725][713-friend->715],e[726][713-friend->717],e[727][713-friend->719],e[728][713-friend->721],e[729][713-friend->723],e[730][717-friend->715],e[731][717-friend->719],e[732][717-friend->721],e[733][721-friend->715],e[734][721-friend->719],v[721],v[715]]
==>[v[712],v[713],v[715],v[717],v[719],v[721],v[723],e[725][713-friend->715],e[726][713-friend->717],e[727][713-friend->719],e[728][713-friend->721],e[729][713-friend->723],e[730][717-friend->715],e[731][717-friend->719],e[732][717-friend->721],e[733][721-friend->715],e[734][721-friend->719],v[721],v[719]]
...
==>[v[712],v[713],v[715],v[717],v[719],v[721],v[723],e[725][713-friend->715],e[726][713-friend->717],e[727][713-friend->719],e[728][713-friend->721],e[729][713-friend->723],e[730][717-friend->715],e[731][717-friend->719],e[732][717-friend->721],e[733][721-friend->715],e[734][721-friend->719],v[719],v[721]]
在sideEffect()
之外添加顶点/边时,它们将包含在该输出中.因此,当您尝试遍历V().as('a')
时,simplePath()
立即将它们过滤掉!
As you've added vertices/edges outside of the sideEffect()
they are included in that output. Therefore, simplePath()
immediately filters them away as soon as you try to traverse V().as('a')
!
==>[v[712],v[713],v[715],v[717],v[719],v[721],v[723],e[725][713-friend->715],e[726][713-friend->717],e[727][713-friend->719],e[728][713-friend->721],e[729][713-friend->723],e[730][717-friend->715],e[731][717-friend->719],e[732][717-friend->721],e[733][721-friend->715],e[734][721-friend->719],v[721],v[715]]
查看v[721]
出现两次的方式-一次用于addV()
,一次用于V()
. simplePath()
看到您遍历了该顶点并返回了该顶点.
See how v[721]
appears twice - once for addV()
and once for V()
. simplePath()
sees that you traversed that vertex and returned to it.
我调试此问题的方法(因为尚未立即弄清答案)是首先profile()
两次遍历并比较相似部分的计数.我注意到它们开始有所不同的地方,这使我对问题开始的地方一目了然.从那里开始,我开始并排执行查询,直到注意到Path
周围的输出差异.您可以在此处上学习一些有关如何区分和调试Gremlin查询的知识.
My approach to debugging this (as the answer was not immediately clear) was to first profile()
the two traversals and compare the counts of the like sections. I noted where they started to differ which put me in the viscinity of where the problem started. From there I started executing the query up to those steps side-by-side until I noted the difference in output around the Path
. You can learn a bit on how to pick apart and debug Gremlin queries here.
这篇关于Gremlin查询是否有效取决于上下文的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!