我正在努力想象一下"之间的关系。图表db中的三个节点之间的关系(例如neo4j)。
说,我想确定B
介于A
和C
之间的事实。我没有节点的任何位置属性(例如,lat / long),我可以使用它来做一个'之间的关系。评价。我只是纯粹认为B在A和C之间。
换句话说,举一个例子,中指位于食指和无名指之间。如果我不知道位置或顺序(我可以将其定义为每个手指的一个属性并使用它),但只是中指位于另外两个手指之间。如何将这个事实存储在图形db或neo4j中。
为了增加复杂性,B也可能在D和E之间。我需要弄清楚如何回答B之间的问题(答案A,C和D,E)或两者之间的问题。 A和C(答案:B)。
如何在图形DB / Neo4j中实现逻辑?
答案 0 :(得分:3)
假设你的意思是节点是由这样的东西创建的线性关系......
create (a:Test {name: 'A'})
create (b:Test {name: 'B'})
create (c:Test {name: 'C'})
create (a)-[:NEXT]->(b)
create (b)-[:NEXT]->(c)
return *
然后你可以匹配路径并检查该路径中是否存在 B 。
match p=(:Test {name: 'A'})-[:NEXT*2..]->(:Test {name: 'C'})
where 'B' in extract(node IN nodes(p) | node.name)
return p
如果您想了解 B 之间的节点,那么您可以从B开始查找相邻节点。如果未在关系中指定向量,则将获得两次相同的节点集,但顺序相反。如果您在where子句中比较相邻节点,则可以将结果列表减少为不同的对。
match (left:Test )--(:Test {name: 'B'})--(right:Test)
where left.name < right.name
return left, right
如果我们创建更多节点(D和E)并将它们连接到B,您可以获得类似的结果。
match (b:Test {name: 'B'})
with b
create (d:Test {name: 'D'})-[:NEXT]->(b)
create (b)-[:NEXT]->(e:Test {name: 'E'})
但除非您以不同的方式命名您的关系或添加其他一些属性,否则您将无法保留不同的曲目。
match (left:Test )-->(:Test {name: 'B'})-->(right:Test)
return left, right
如果我们通过在节点之间创建特定关系来稍微转换数据,那么我们可以更好地控制我们返回的内容。
// create the 'A_LINE'
match (a:Test {name: 'A'})-->(b:Test {name: 'B'})-->(c:Test {name: 'C'})
create (a)-[:A_LINE]->(b)-[:A_LINE]->(c)
// create the 'D_LINE'
match (d:Test {name: 'D'})-->(b:Test {name: 'B'})-->(e:Test {name: 'E'})
create (d)-[:D_LINE]->(b)-[:D_LINE]->(e)
例如,现在您可以询问特定关系类型的项目。
// return adjacent nodes on the 'A_LINE'
match (left:Test )-[:A_LINE]->(:Test {name: 'B'})-[:A_LINE]->(right:Test)
return left, right
// return adjacent nodes on the 'D_LINE'
match (left:Test )-[:D_LINE]->(:Test {name: 'B'})-[:D_LINE]->(right:Test)
return left, right
或者稍作努力,您可以同时询问不同的行,并在事后将其分类为适当的组合。
match p=(:Test )-[:A_LINE|D_LINE]->(:Test {name: 'B'})-[:A_LINE|D_LINE]->(:Test)
with p, relationships(p) as rels
unwind rels as r
with p, collect(distinct type(r)) as rels
where size(rels) = 1
return head(rels), head(nodes(p)), last(nodes(p))