2014-12-11 5 views
2

Здравствуйте, я пытаюсь соответствовать Neo4j отношения, используя «где и»Neo4j, матч Отношения ГДЕ И

Мой пример relationiship является: «Визиты Пользователь Страна»

Я создаю это как так ...

MATCH (c:Country{Name:Country}) MERGE (u:User{Email:Email,UserID: UserID}) MERGE (u)-[r:Visits]->(c) 
//Countries are previously created and Users may or may not exist 

Тогда я запрашиваю (это работает):

MATCH (u:User)-[r:Visits]->(c:Country) where c.Name='France' or c.Name='Spain' return u 

Результат: Показывает мне все пользователи, посетившие Spa в ИЛИ Франции, даже если они только посетили одну из двух стран.

BUT Что я пытаюсь сделать, это тот же самый точный запрос, но с 'AND' вместо 'OR'. В котором я могу получить пользователей, которые посетили как «Францию», так и «Испанию».

MATCH (u:User)-[r:Visits]->(c:Country) where c.Name='France' AND c.Name='Spain' return u 

Результат: 0 узлы и отношения найдены ..

Что я могу сделать?

ответ

6

В вашем запросе вы соглашаетесь с одним узлом страны и заявляете, что имя этого узла должно быть France и должно быть Spain.

Вы хотите найти всех пользователей, которые посетили Францию ​​и Испанию. Есть несколько способов, вы можете идти ...

//match both countries against the same user and identify them separtely 
//making two matches in a single query 
MATCH (u:User)-[:VISITS]->(c1:Country), (u)-[:VISITS]->(c2:Country) 
WHERE c1.name = "France" 
AND c2.name = "Spain" 
RETURN u.name 

//match all users that have been to either and only return the one that have been to both 
MATCH (u:User)-[r:VISITS]->(c:Country) 
WHERE (c.name IN [ "France", "Spain"]) 
WITH u, count(*) AS num 
WHERE num = 2 
RETURN u.name, num 

Это кажется, номер один лучше, так как это является более точным и, вероятно, более эффективным.

3

Если вас беспокоит только 2 страны. этот запрос также будет работать, в дополнение к опциям, предоставленным @DaveBennett.

MATCH (c1)<-[:VISITS]-(u)-[:VISITS]->(c2) 
WHERE c1.name = "France" AND c2.name = "Spain" 
RETURN u.name; 
1

Что плохого в запросе

MATCH (u:User)-[r:Visits]->(c:Country) 
where c.Name='France' 
AND c.Name='Spain' 
return u 

Это всегда будет возвращать никаких строк, потому что вы пытаетесь проверить два значения для одного и того же имущества узла.

Решение

MATCH (c1:Country)<-[r:Visits]-(u:user)-[r1:Visits]->(c2:Country) 
WHERE c1.name = 'France' AND c2.name = 'Spain' 
RETURN u.name; 

Это вернет то, что вам нужно.

Вот один короткий и полезный справочный документ о Neo4j: http://neo4j.com/docs/2.1.2/cypher-refcard/

+0

Сатиш, как ваш ответ отличается от cybersam (кроме этикетки, конечно)? –

Смежные вопросы