此问题是我之前询问的问题here(甚至更早版本here)的直接扩展。
假设我有一个如下所示的图形数据库:
就像我之前提出的问题一样,唯一真正有趣的是SomeProperty
可以是'是'或'否'。
在第一行中,三个节点中的一个对此属性具有“是”。
在底行,五个节点中的3个节点对此属性具有“是”。
(轻微的哲学旁注:我开始怀疑这是一个糟糕的图形模式。为什么?因为,在每组节点中,每个节点都连接到每个其他节点。我我并不担心有两组节点这一事实,但事实上,当我填充这个图时,我会得到说话,'返回530行'。我认为这意味着实际上在图结构中创建了530个子路径,这看起来有点矫枉过正。)
无论如何,我试图解决的问题与我试图在更早,更简单,更线性的上下文here中解决的问题几乎相同。
我想返回这些不相交图中的任何一个的完整路径,而在所述图中的任何位置,SomeProperty
的出现次数大于2。
我认为这是一个常见的简单问题。例如,假设你有两个不相关的家庭,有人说,“让我和家人在一起有两个以上的左撇子。”
超级聪明的#cybersam建议更简单地体现这个问题,这有点像:
MATCH p=(a:person)-[:RELATED_TO*]->(b:person)
WHERE
NOT ()-[:RELATED_TO]->(a) AND
NOT (b)-[:RELATED_TO]->() AND
2 < REDUCE(s = 0, x IN NODES(p) | CASE WHEN x. SomeProperty = 'Yes' THEN s + 1 ELSE s END)
RETURN p;
...如果图形更像是一条直线,并且没有集合中的每个节点与每个其他节点相关,那么它的效果很好。
我认为#cybersam的查询无法处理这个更复杂的图表的原因是因为没有终端节点。
(另一个哲学旁注:我开始提出一种理论,即图形中密集,错综复杂的关系会带来组合问题,性能和查询。我认为这可能是应有的查询时Cypher使用的双向性?)
这是我的数据。任何建议都表示赞赏,感谢您帮助我攀登学习曲线。
// match (n) detach delete n;
CREATE (albert:person {gender: 'Male', name: 'Albert', SomeProperty: 'Yes'})
CREATE (annie:person {gender: 'Female', name: 'Annie', SomeProperty: 'No'})
CREATE (adrian:person {gender: 'Female', name: 'Adrian', SomeProperty: 'No'})
CREATE (albert)-[:RELATED_TO]->(annie)
CREATE (annie)-[:RELATED_TO]->(albert)
CREATE (annie)-[:RELATED_TO]->(adrian)
CREATE (adrian)-[:RELATED_TO]->(annie)
CREATE (albert)-[:RELATED_TO]->(adrian)
CREATE (adrian)-[:RELATED_TO]->(albert)
CREATE (bill:person {gender: 'Male', name: 'Bill', SomeProperty: 'Yes'})
CREATE (barb:person {gender: 'Female', name: 'Barb', SomeProperty: 'Yes'})
CREATE (barry:person {gender: 'Male', name: 'Barry', SomeProperty: 'Yes'})
CREATE (bart:person {gender: 'Male', name: 'Bart', SomeProperty: 'No'})
CREATE (bartholemu:person {gender: 'Male', name: 'Bartholemu', SomeProperty: 'No'})
CREATE (bill)-[:RELATED_TO]->(barb)
CREATE (barb)-[:RELATED_TO]->(bill)
CREATE (barb)-[:RELATED_TO]->(barry)
CREATE (barry)-[:RELATED_TO]->(barb)
CREATE (barry)-[:RELATED_TO]->(bart)
CREATE (bart)-[:RELATED_TO]->(barry)
CREATE (bart)-[:RELATED_TO]->(bartholemu)
CREATE (bartholemu)-[:RELATED_TO]->(bart)
CREATE (bill)-[:RELATED_TO]->(bartholemu)
CREATE (bartholemu)-[:RELATED_TO]->(bill)
答案 0 :(得分:1)
如果这是关于人的家庭,那么最简单的解决方法是为每个关系组添加一个:Family节点,如下所示:
create (f:Family) with f
match (a:person {name:"Adrian"})-[:RELATED_TO*]->(b:person)
merge (f:Family)<-[:FAMILY]-(a)
merge (f:Family)<-[:FAMILY]-(b)
将“Adrian”改为“Barry”以创建第二个家庭组。
这为您提供了一个核心:每个家庭组的家庭节点。然后你可以选择有足够的家庭组:person.SomeProperty =“是”家庭成员如此:
// Find families with 2 or more :person.SomeProperty = "yes"
match p = (f:Family)<-[:FAMILY]-(psn:person)
where psn.SomeProperty = "Yes"
with f, count(psn) as cnt
where cnt > 2
// Get the family members
match (a:person)<-[r1:RELATED_TO]-(b:person)-[r2:RELATED_TO*]->(c)
where (a)-[:FAMILY]-(f)
and a = c // to get all the nodes in the loop
// report the first record which'll have two
// family members and all the relationships
return a, r1, b, r2
limit 1