如何在 Gremlin 的同一父节点下的节点内创建边
How to create edges within nodes under the same parent node in Gremlin
我是 Gremlin 的新手。我想用“兄弟”边缘连接同一个“父”节点下的“子”节点。
初始状态:
- (:parent {name: 'A'})-[parent_of]->(:child {'name: 'A1'})
- (:parent {name: 'A'})-[parent_of]->(:child {'name: 'A2'})
- (:parent {name: 'B'})-[parent_of]->(:child {'name: 'B1'})
- (:parent {name: 'B'})-[parent_of]->(:child {'name: 'B2'})
预计:
- 初始状态+
- (:child {name: 'A1'})-[sibling]->(:child {'name: 'A2'})
- (:child {name: 'A2'})-[sibling]->(:child {'name: 'A1'})
- (:child {name: 'B1'})-[sibling]->(:child {'name: 'B2'})
- (:child {name: 'B2'})-[sibling]->(:child {'name: 'B1'})
预期图像:
Expected Illustration
我应该如何为此编写 gremlin 查询?
所以给定这张图
g.addV('Parent').property('name','A').as('a').
addV('Parent').property('name','B').as('b').
addV('Child').property('name','A1').as('a1').
addV('Child').property('name','A2').as('a2').
addV('Child').property('name','B1').as('b1').
addV('Child').property('name','B2').as('b2').
addE('parent-of').from('a').to('a1').
addE('parent-of').from('a').to('a2').
addE('parent-of').from('b').to('b1').
addE('parent-of').from('b').to('b2').iterate()
我们可以通过几种不同的方式添加兄弟关系。这真的只取决于你想如何查找兄弟姐妹。虽然我没有在上面显示它,但在 Gremlin 中很常见,为每个顶点提供一个自定义 ID 并使用它来查找顶点。在这个例子中,我将只按名称查找它们。
要找到每个 parent 的 children,我们可以从一个简单的查询开始,例如:
g.V().hasLabel('Parent').out()
或者我们可以使用
g.V().hasLabel('Child')
鉴于我们已经找到 children,我们只需要扩展查询以将这些查询与共同的 parent 连接起来。实际上有很多方法可以编写此查询(稍后我将尝试重新访问此答案以展示其他一些方法并讨论可能的优化)。这应该给你一些基本的构建块。
gremlin> g.V().hasLabel('Parent').as('p').
......1> out().as('c').
......2> addE('sibling').
......3> to(V().hasLabel('Child').where(neq('c')).where(__.in('parent-of').as('p'))
......4> )
==>e[40][24-sibling->26]
==>e[41][26-sibling->24]
==>e[42][28-sibling->30]
==>e[43][30-sibling->28]
验证它是否有效
gremlin> g.V().hasLabel('Child').out('sibling').path().by('name')
==>[A1,A2]
==>[A2,A1]
==>[B1,B2]
==>[B2,B1]
在大图(例如大家谱)中,这可能是一个昂贵的查询,针对特定的 parents 或 children 显然是一个很好的优化。
编辑添加:
这是实现相同目标的另一种方法,但从每个 child 开始,遍历回 parent,然后再到兄弟姐妹,同时避免与自己建立联系。
gremlin> g.V().hasLabel('Child').as('c').
......1> addE('sibling').
......2> to(__.in('parent-of').out('parent-of').where(neq('c')))
==>e[84][68-sibling->70]
==>e[85][70-sibling->68]
==>e[86][72-sibling->74]
==>e[87][74-sibling->72]
我是 Gremlin 的新手。我想用“兄弟”边缘连接同一个“父”节点下的“子”节点。
初始状态:
- (:parent {name: 'A'})-[parent_of]->(:child {'name: 'A1'})
- (:parent {name: 'A'})-[parent_of]->(:child {'name: 'A2'})
- (:parent {name: 'B'})-[parent_of]->(:child {'name: 'B1'})
- (:parent {name: 'B'})-[parent_of]->(:child {'name: 'B2'})
预计:
- 初始状态+
- (:child {name: 'A1'})-[sibling]->(:child {'name: 'A2'})
- (:child {name: 'A2'})-[sibling]->(:child {'name: 'A1'})
- (:child {name: 'B1'})-[sibling]->(:child {'name: 'B2'})
- (:child {name: 'B2'})-[sibling]->(:child {'name: 'B1'})
预期图像: Expected Illustration
我应该如何为此编写 gremlin 查询?
所以给定这张图
g.addV('Parent').property('name','A').as('a').
addV('Parent').property('name','B').as('b').
addV('Child').property('name','A1').as('a1').
addV('Child').property('name','A2').as('a2').
addV('Child').property('name','B1').as('b1').
addV('Child').property('name','B2').as('b2').
addE('parent-of').from('a').to('a1').
addE('parent-of').from('a').to('a2').
addE('parent-of').from('b').to('b1').
addE('parent-of').from('b').to('b2').iterate()
我们可以通过几种不同的方式添加兄弟关系。这真的只取决于你想如何查找兄弟姐妹。虽然我没有在上面显示它,但在 Gremlin 中很常见,为每个顶点提供一个自定义 ID 并使用它来查找顶点。在这个例子中,我将只按名称查找它们。
要找到每个 parent 的 children,我们可以从一个简单的查询开始,例如:
g.V().hasLabel('Parent').out()
或者我们可以使用
g.V().hasLabel('Child')
鉴于我们已经找到 children,我们只需要扩展查询以将这些查询与共同的 parent 连接起来。实际上有很多方法可以编写此查询(稍后我将尝试重新访问此答案以展示其他一些方法并讨论可能的优化)。这应该给你一些基本的构建块。
gremlin> g.V().hasLabel('Parent').as('p').
......1> out().as('c').
......2> addE('sibling').
......3> to(V().hasLabel('Child').where(neq('c')).where(__.in('parent-of').as('p'))
......4> )
==>e[40][24-sibling->26]
==>e[41][26-sibling->24]
==>e[42][28-sibling->30]
==>e[43][30-sibling->28]
验证它是否有效
gremlin> g.V().hasLabel('Child').out('sibling').path().by('name')
==>[A1,A2]
==>[A2,A1]
==>[B1,B2]
==>[B2,B1]
在大图(例如大家谱)中,这可能是一个昂贵的查询,针对特定的 parents 或 children 显然是一个很好的优化。
编辑添加:
这是实现相同目标的另一种方法,但从每个 child 开始,遍历回 parent,然后再到兄弟姐妹,同时避免与自己建立联系。
gremlin> g.V().hasLabel('Child').as('c').
......1> addE('sibling').
......2> to(__.in('parent-of').out('parent-of').where(neq('c')))
==>e[84][68-sibling->70]
==>e[85][70-sibling->68]
==>e[86][72-sibling->74]
==>e[87][74-sibling->72]