遍历有限制的图

traversing a graph with restrictions

我正在探索 TinkerPop 和 Gremlin,想了解 language/syntax 是否支持以下图形问题和遍历

(我想如果是这样的话,TinkerPop "enabled" 图 [AWS Neptun/OrientDB/Girafe/..] 也会支持它吗?)

(如果您知道任何可以满足我要求的图形数据库,请告诉我)

假设我们有:

任何两个顶点都可以通过任何类型的边连接

例如

我们的输入:

我们的output/answer:

从 'input vertex' 开始,找到 type/label 'A' 的任何顶点,其值等于 'input value'

我们的限制:

图的遍历必须遵循以下规则:

p.s。答案可以是路径或子树或节点的 id 或 yes/no 我不管,只要能答出图的问题

例如(来自上图示例)

输入: 顶点 ID = 3 & 值 = 56

输出: 顶点 ID = 5

让我们从你的示例图开始(在以后的问题中,如果你能提供这个脚本就好了):

g = TinkerGraph.open().traversal()
g.addV('A').
    property(id, 3).                     /* should probably be 56 */
    property('Value', 6).as('A3').
  addV('A').
    property(id, 4).
    property('Value', 56).as('A4').
  addE('soft').from('A4').
  addV('A').
    property(id, 5).
    property('Value', 56).as('A5').
  addV('B').
    property(id, 1).
    property('Value', '0x11').as('B1').
  addE('hard').from('A3').
  addV('B').
    property(id, 2).
    property('Value', '0x01').as('B2').
  addE('med').from('B1').
  addV('C').
    property(id, 7).
    property('Value', 'S').as('C7').
  sideEffect(addE('soft').from('B1')).
  addE('hard').to('A5').
  addV('C').
    property(id, 8).
    property('Value', 'J').
  sideEffect(addE('hard').from('B2')).
  sideEffect(addE('med').to('C7')).
  addE('med').from('A3').
  iterate()

按照您的遍历规则进行的遍历为:

g.V(3).as('input').     /* don't filter by 'Value', filtering by id is enough */
  repeat(choose(label).
           option('A', out('hard').hasLabel('B')).
           option('B', out('med','hard').hasLabel('B', 'C')).
           option('C', union(out('med','hard').hasLabel('B', 'C'),
                             out('hard').hasLabel('A'))).
         dedup()).
    emit(where(eq('input')).by('Value'))

...但正如我在评论中提到的,您的示例图表存在问题。

但是,如果我将顶点 3 的 Value 更改为 56,我们得到:

gremlin> g.V(3).as('input').
......1>   repeat(choose(label).
......2>            option('A', out('hard').hasLabel('B')).
......3>            option('B', out('med','hard').hasLabel('B', 'C')).
......4>            option('C', union(out('med','hard').hasLabel('B', 'C'),
......5>                              out('hard').hasLabel('A'))).
......6>          dedup()).
......7>     emit(where(eq('input')).by('Value'))
==>v[5]