【发布时间】:2014-04-08 18:05:34
【问题描述】:
在 Titan(hbase) 图中,我想获得给定节点的共同祖先。 使用 gremlin 有什么办法可以得到共同的祖先? 或者任何其他 Utils / libs 可用于在给定节点的 Titan 图中查找共同祖先?
【问题讨论】:
在 Titan(hbase) 图中,我想获得给定节点的共同祖先。 使用 gremlin 有什么办法可以得到共同的祖先? 或者任何其他 Utils / libs 可用于在给定节点的 Titan 图中查找共同祖先?
【问题讨论】:
我将对您在此处寻找的确切内容做出一些假设,但也许这个答案将有助于激发您想出您正在寻找的东西。我使用toy graph 来演示这种方法,并假设边缘定向指向孩子。显然这不是一棵完美的树,但那里有足够的数据至少可以证明遍历。下面显示了我想为其寻找祖先的“孩子”:
gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> children = [g.v(2),g.v(5),g.v(6)]
==>v[2]
==>v[5]
==>v[6]
我可以通过祖先递归循环遍历树并查看如下路径:
gremlin> children._().in.loop(1){it.loops<5}{true}.path
==>[v[2], v[1]]
==>[v[5], v[4]]
==>[v[5], v[4], v[1]]
上面的行将循环限制在距离祖先 5 步的位置,{true} 闭包只是意味着在循环的所有步骤中输出值。一个共同的祖先将是每条路径终止不止一次的祖先:
gremlin> children._().in.loop(1){it.loops<5}{true}.groupCount.cap.next().findAll{it.value>1}
==>v[1]=2
从这个意义上说,v[1] 是三个子节点中唯一的共同祖先,三个子节点中只有两个共享该祖先。为了让它更有趣,让我们将顶点6连接到顶点4并重新执行遍历:
gremlin> children._().in.loop(1){it.loops<5}{true}.groupCount.cap.next().findAll{it.value>1}
==>v[1]=3
==>v[4]=2
现在顶点4 被包含为共同祖先。它有顶点6 和5 的孩子。鉴于顶点 4 的共享性质,6 现在也共享顶点 1,因此祖先现在由所有三个顶点共享。
更新:以上答案适用于 TinkerPop 2.x,以下适用于 TinkerPop 3.x。
鉴于这棵树:
gremlin> g.addV().property(id, 'A').as('a').
addV().property(id, 'B').as('b').
addV().property(id, 'C').as('c').
addV().property(id, 'D').as('d').
addV().property(id, 'E').as('e').
addV().property(id, 'F').as('f').
addV().property(id, 'G').as('g').
addE('hasParent').from('a').to('b').
addE('hasParent').from('b').to('c').
addE('hasParent').from('d').to('c').
addE('hasParent').from('c').to('e').
addE('hasParent').from('e').to('f').
addE('hasParent').from('g').to('f').iterate()
您可以通过以下方式找到共同祖先:
gremlin> g.V('A').
......1> repeat(out('hasParent')).emit().as('x').
......2> repeat(__.in('hasParent')).emit(hasId('D')).
......3> select('x').limit(1)
==>v[C]
TinkerPop recipes 对此主题进行了更全面的讨论。
【讨论】: