Cypher查询以按属性查找与其他节点无关的节点

时间:2016-05-26 14:30:02

标签: neo4j cypher

考虑以下数据库结构:

DB structure

为方便起见,您可以使用以下方式创建:

create (p1:Person {name: "p1"}),(p2:Person {name: "p2"}),(p3:Person {name: "p3"}),(e1:Expertise {title: "Exp1"}),(e2:Expertise {title: "Exp2"}),(e3:Expertise {title: "Exp3"}),(p1)-[r1:Expert]->(e1),(p1)-[r2:Expert]->(e2),(p2)-[r3:Expert]->(e2),(p3)-[r4:Expert]->(e3),(p2)-[r5:Expert]->(e3)

我希望能够找到与特定Person节点相关的所有Expertise个节点,例如“EXP2”

我试过

MATCH (p:Person)--(e:Expertise)
WHERE NOT (e.title = "Exp2")
RETURN p

但它会返回所有Person个节点(我希望它只返回p3)。

从逻辑上讲,这个结果很有意义,因为每个节点都与至少一个Expertise Exp2不相关。 但我想要的是找到与Person无关的所有Exp2个节点,即使它们也与其他节点相关。

如何做到这一点?

修改

似乎我不清楚要求。这是一种(非常)简化的方式,用更复杂的数据库来表示我的问题 考虑Expertise有更多属性的可能性,我想在同一个查询中使用(不一定是否定)。例如:

MATCH (p)--(e) 
WHERE e.someProp > 5 AND e.anotherProp = "cookie" AND NOT e.title = "Exp2"

2 个答案:

答案 0 :(得分:4)

更新

您需要更多地限制它,仅限于此人

MATCH (p:Person), (e:Expertise {title="Exp2"})
WHERE NOT (p)-[]->(e)
RETURN p

我认为你可以使用<>运算符:

MATCH (p:Person)--(e:Expertise)
WHERE e.title <> "Exp2"
RETURN p

或者你可以用一种模式表达它:

MATCH (p:Person)
WHERE NOT EXISTS((p)--(e:Expertise {title:"Exp2"}))
RETURN p

答案 1 :(得分:1)

来自@ChristopheWillemsen的小改变查询:

MATCH (e:Expertise) WHERE e.someProperty > 5 AND NOT e.title = someValue
WITH collect(e) as es
MATCH (p:Person) WHERE all(e in es WHERE NOT Exists( (p)--(e) ) )
RETURN p

更新:

// Collect the `Expertise` for which the following conditions:
MATCH (e:Expertise) WHERE e.num > 3 AND e.title = 'Exp2'
WITH collect(e) as es

// Select the users who do not connect with any of of expertise from `es` set:
OPTIONAL MATCH (p:Person) WHERE all(e in es WHERE NOT Exists( (p)--(e) ) )
RETURN es, collect(p)

另一个有一些优化的查询:

// Get the set of `Expertise-node` for which the following conditions:
MATCH (e:Expertise) WHERE e.num > 3 AND e.title = 'Exp2'

// Collect all `Person-node` connected to node from the `Expertise-node` set:
OPTIONAL MATCH (e)--(p:Person)
WITH collect(e) as es, collect(distinct id(p)) as eps

//Get all `Person-node` not in `eps` set:
OPTIONAL MATCH (p:Person) WHERE NOT id(p) IN eps
RETURN es, collect(p)