Graph 小精灵查询:如何与&;还是关系?

Graph 小精灵查询:如何与&;还是关系?,graph,nodes,gremlin,traversal,tinkerpop,Graph,Nodes,Gremlin,Traversal,Tinkerpop,比如说,我有A、B、C或D类型的边 如何在这些边类型上使用AND和OR进行遍历 假设我想从节点X通过(in(A)和out(B))或(C)和out(D))进行遍历 我期望的结果是所有节点都至少有一个A边指向X,至少有一个B边指向X,或者至少有一个C边指向或指向X,至少有一个D边指向X 在一般情况下,如何编写一个Gremlin查询来实现这一点?非常感谢你的帮助 我想出来了 g.V().union( // in(A) AND out(B) match( __.as('1').in('

比如说,我有A、B、C或D类型的边

如何在这些边类型上使用AND和OR进行遍历

假设我想从节点X通过(in(A)和out(B))或(C)和out(D))进行遍历

我期望的结果是所有节点都至少有一个A边指向X,至少有一个B边指向X,或者至少有一个C边指向或指向X,至少有一个D边指向X

在一般情况下,如何编写一个Gremlin查询来实现这一点?非常感谢你的帮助

我想出来了

g.V().union(

  // in(A) AND out(B)
  match(
    __.as('1').in('A').as('2'),
    __.as('1').out('B').as('2'))
  .select('2'),

  // OR

  // both(C) AND out(D)
  match(
    __.as('1').both('C').as('2'),
    __.as('1').out('D').as('2'))
  .select('2'))

// Delete duplicates
.dedup()

使用这个简单的图形

g.addV('1').as('1').
  addV('2').as('2').
  addV('3').as('3').
  addV('4').as('4').
  addV('5').as('5').
  addE('B').from('2').to('3').
  addE('A').from('3').to('2') 
您的初始
匹配
步骤

gremlin> g.V().
......1>   match(
......2>     __.as('1').in('A').as('2'),
......3>     __.as('1').out('B').as('2')).
......4>   select('2').by(label)

==>3
可以简化为

gremlin> g.V().as('1').out('B').filter(out('A').as('1')).label()

==>3 
请注意,仅使用了
out
步骤。第一个会将您带到任何相邻顶点。第二个,在过滤器内部,查看是否有回到您的来源的方法(从当前顶点的角度来看,这是另一种
out
关系)


您可以使用相同的模式替换另一个
匹配的
。如果您确实想要
行为,则可以将查询包装在
步骤中;如果您确实想要所有符合约束条件的结果,则可以继续使用
union

您还应该能够获得相同的结果,将
union
步骤替换为
步骤并替换
match
使用更简单的
步骤,其中
步骤。我将用一个例子补充另一个答案。谢谢!总是很高兴有一个不同的方式做这件事。您知道哪种解决方案可能是最有效的,或者它们几乎是一样的吗?:)它将取决于后端图形数据库引擎。一般来说,我总是运行测试来确定哪一个更好。一些查询优化器可能不会处理
匹配
步骤以及其他一些步骤,但我肯定会使用代表性数据运行测试来找到答案。如果我想不出其他方法,我倾向于只使用
match
,部分原因是我认为有时查询会变得比读者需要的更复杂,如果不是优化器也需要的话。