有限制地遍历图

时间:2018-07-24 18:07:45

标签: graph graph-databases gremlin tinkerpop3

我正在研究TinkerPop和Gremlin,想了解该语言/语法是否将支持以下图形问题和遍历

(我想如果是的话,TinkerPop“启用”图形[AWS Neptun / OrientDB / Girafe / ..]也将支持它吗?)

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

让我们说:

  • 3种顶点:A,B,C
  • 3种类型的边缘:硬,中,软

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

例如 Example Graph Image

我们的输入:

  • 开始顶点
  • 寻找价值

我们的输出/答案:

从“输入顶点”开始,找到任何类型/标签为“ A”且值等于“输入值”的顶点

我们的限制:

遍历图形只能在以下规则下进行:

  • 根据顶点类型/标签,我们只能从顶点“ A”移动到顶点“ B” “硬”
  • 如果edge.label =='Medium'||,则可以从B或C移至B或C。 edge.label =='硬'
  • 只有在edge.label =='Hard'时,我们才能从C移到A

p.s。答案可以是路径或子树或节点的ID或是/否 我不在乎,只要我们能回答图表问题

例如(来自上面的图片示例)

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

输出:顶点ID = 5

1 个答案:

答案 0 :(得分:3)

让我们从示例图开始(在以后的问题中,如果您可以提供此脚本,那就更好了):

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]