Gremlin查询是否有效取决于上下文
在一个查询中(由stephen mallette在中编写),问题是它在gremlify中工作,但是当我将它粘贴到我的项目中时,会给出错误的输出 因此,我打开了gremlify来编写一个数据创建查询,然后将其粘贴到gremlin控制台中,以便在那里进行测试。我注意到,如果它在查询的数据创建部分之后执行,它在gremlify中不起作用,据我所知,它应该可以工作 问题是:Gremlin查询是否有效取决于上下文,gremlin,tinkerpop,tinkerpop3,gremlin-server,Gremlin,Tinkerpop,Tinkerpop3,Gremlin Server,在一个查询中(由stephen mallette在中编写),问题是它在gremlify中工作,但是当我将它粘贴到我的项目中时,会给出错误的输出 因此,我打开了gremlify来编写一个数据创建查询,然后将其粘贴到gremlin控制台中,以便在那里进行测试。我注意到,如果它在查询的数据创建部分之后执行,它在gremlify中不起作用,据我所知,它应该可以工作 问题是: g.V().as('a'). repeat(both().simplePath()). times(2). whe
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())
在这里它工作,输出是正确的:
这里它给出了一个不正确的输出:
(相同的图形,但通过查询创建)
在这里,它根本不提供任何输出:
(与之前相同,第1行有所变化)
在我的项目中,也给出了不正确的输出,在查询之前,我不会像上面的gremlify项目那样执行任何奇怪的操作
还有一个查询也是这样做的,我自己写的,效率较低,但在所有相同的情况下都能完美工作,在我的项目中,请参见:
在我的项目中,我使用Node.js在本地连接到gremlin服务器,默认配置未被更改
这里发生了一些我不理解的事情。通过扩展遍历,您已经扩展了
路径。将addV('j')
放在遍历的前面会添加一些我的原始算法没有考虑到的内容:
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]
您可以通过命名您关心的路径或限制或过滤掉初始路径元素来说明这一点:
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”处启动路径,然后查询再次开始工作
关于不使用sideEffect()
添加示例图形数据的另一个示例,请注意path()
在repeat()
之后的输出:
当您在sideEffect()
之外添加顶点/边时,它们将包含在该输出中。因此,simplePath()
在您尝试遍历V().as('a')
时,会立即将它们过滤掉
查看v[721]
如何显示两次-一次用于addV()
,一次用于v()
simplePath()
看到您遍历了该顶点并返回到该顶点
我调试这个的方法(因为答案不是很清楚)是首先profile()
两次遍历并比较相似部分的计数。我注意到他们之间的分歧,这让我意识到问题是从哪里开始的。从那时起,我开始并行执行这些步骤,直到我注意到路径
周围输出的差异。您可以学习如何分离和调试小精灵查询。通过扩展遍历,您已经扩展了路径。将addV('j')
放在遍历的前面会添加一些我的原始算法没有考虑到的内容:
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]
您可以通过命名您关心的路径或限制或过滤掉初始路径元素来说明这一点:
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”处启动路径,然后查询再次开始工作
关于不使用sideEffect()
添加示例图形数据的另一个示例,请注意path()
在repeat()
之后的输出:
当您在sideEffect()
之外添加顶点/边时,它们将包含在该输出中。因此,simplePath()
在您尝试遍历V().as('a')
时,会立即将它们过滤掉
查看v[721]
如何显示两次-一次用于addV()
,一次用于v()
simplePath()
看到您遍历了该顶点并返回到该顶点
我调试这个的方法(因为答案不是很清楚)是首先profile()
两次遍历并比较相似部分的计数。我注意到他们之间的分歧,这让我意识到问题是从哪里开始的。从那时起,我开始并行执行这些步骤,直到我注意到路径
周围输出的差异。您可以学习如何分离和调试Gremlin查询。我发布的一个问题仍然无法通过添加from('a')来解决,这一个问题:我通过删除simplePath()来解决,因为我注意到simplePath()之后没有返回任何内容。我不知道为什么会发生这种情况。也许你可以给我一些关于这方面的信息。通过在那些addV()
和addE()
调用中不产生副作用,你已经在路径上放置了更多的对象。这些新添加的顶点将立即在第一个both()
和simplePath()
上显示一个循环,并将它们过滤掉。如果您添加以下内容,可以看到效果:V().as('a')。在最后一个addE()
之后添加两个()。据我所知,使用V()选择图形的所有顶点与选择这些顶点是一样的,因为我是使用addV()创建它们的。为什么simplePath()会以不同的方式运行取决于顶点的选择方式?我已经更新了我的答案,并解释了我要求您使用V().as('a').both().path()
-希望现在可以理解。路径
不仅仅是你通过的V()
——它是Gremlin通过的所有元素,包括突变、转换等。你想得对simplePath()
过滤步骤的结果。在我的示例中,path()
的结果包括由addV()
步骤创建的所有顶点,因此当您使用V()
遍历所有顶点时,立即创建一个循环