2016-06-28 6 views
0

私のユースケースはProblemは、単一の問題に対して複数の(Problem)-[:CONATINS]->(Tag)関係があるTagすなわちと「1対多」の関係を持つことができるノードProblemTagの2種類が含まれています(無視する任意の関係を一致するノードを除外構文)。タグの指定された配列で、私はCYPHERクエリは、これらのTagのNeo4jは

サンプルノードのいずれか含まれていませんProblem取得したい:

Problem {id:101, rank:2.389}を。あなたのケースではTag {name: "python"}

答えて

0

は、この例のデータセットを考えてみましょう:

CREATE (p1:Problem {id:1}), 
     (p2:Problem {id:2}), 
     (p3:Problem {id:3}), 

     (t1:Tag {name:'python'}), 
     (t2:Tag {name:'cypher'}), 
     (t3:Tag {name:'neo4j'}), 
     (t4:Tag {name:'ruby'}), 

     (t1)-[:TAGS]->(p1), 
     (t2)-[:TAGS]->(p1), 
     (t2)-[:TAGS]->(p2), 
     (t3)-[:TAGS]->(p2), 
     (t3)-[:TAGS]->(p3), 
     (t4)-[:TAGS]->(p3) 

enter image description here

あなたがpythonまたはcypherによってタグ付けされていない問題をしたい場合は、あなたが唯一の問題をしたいです3が返されます。

MATCH (t:Tag) 
WHERE t.name IN ['python', 'cypher'] 
MATCH (p:Problem) 
WITH p, sum(size((t)-[:TAGS]->(p))) AS matches 
WHERE matches = 0 
RETURN p; 

これが唯一の問題3.

+0

ありがとうalot @ nicole-white :)私のために完全に働いた – esquarer

0

、あなたはMATCHに他のTagのノード(ただし、あなたのリストにあるもの)に接続されているTagとノードへの接続を持っていない、両方のノードを持っています。私は2つのクエリでこれを分割します:

// unconnected nodes 
MATCH (p:Problem) 
WHERE NOT (p)-[:CONTAINS]-() 
RETURN p 
// combine queries with union (both have to return the same) 
UNION 
// nodes which fullfill you criterion 
MATCH (p:Problem)-[:CONTAINS]->(t:Tag) 
// collect distinct Problem nodes with a list of associated Tag names 
WITH DISTINCT p, collect(t.name) AS tag_name 
// use a none predicate to filter all Problems where none 
// of the query tag names are found 
WHERE none(x IN ['python', 'java', 'haskell'] WHERE x IN tag_name) 
RETURN p 
+0

ノーを返し、私はそれらの「1対多」の関係のいずれかのために一致します。もし問題が指定されたタグの1つを持っていても、それは除外されます – esquarer

+0

本当に、私はあなたが 'Tags 'のどれかが存在すればノードを除外したいと思っていました。もう一つの答えが働いていますが、私はあなたが 'none'述語でこれを行うこともできると思います。 –