2016-06-03 2 views
1

У меня есть база данных графа, где есть пользовательские и узлы интереса, которые связаны IS_INTERESTED отношений. Я хочу найти интересы, которые не выбраны пользователем. Я написал этот запрос и он не работаетCypher Query не возвращает несуществующие отношения

OPTIONAL MATCH (u:User{userId : 1})-[r:IS_INTERESTED] -(i:Interest) 
WHERE r is NULL 
Return i.name as interest 

Согласно ответам на подобные вопросы на SO (например, this один), приведенный выше запрос должен work.However, в этом случае она возвращает нуль. Но при выполнении следующего запроса работает, как ожидалось:

MATCH (u:User{userId : 1}), (i:Interest) 
WHERE NOT (u) -[:IS_INTERESTED] -(i) 
return i.name as interest 

причина, почему я не хочу, чтобы запустить приведенный выше запрос, потому что Neo4j выдает предупреждение:

Этот запрос строит декартово произведение между отключенными шаблонами.

Если часть запроса содержит несколько несвязанных шаблонов, это будет строить декартовую продукцию между всеми этими частями. Это может производить большой объем данных и замедлять обработку запросов. В то время как иногда предназначено, это часто может быть возможно переформулирует запроса, который избегает использования этого перекрестного продукта, возможно, путем добавления отношения между различными частями или с помощью ДОПОЛНИТЕЛЬНОГО MATCH (идентификатор: (я))

Что я делаю неправильно в первом запросе, где я использую ДОПОЛНИТЕЛЬНАЯ МАТЧА, чтобы найти несуществующие отношения?

ответ

1

1) MATCH ищет образец в целом, и если он не может найти его целиком - ничего не возвращает.

2) Я думаю, что этот запрос будет эффективным:

// Take all user interests 
MATCH (u:User{userId: 1})-[r:IS_INTERESTED]-(i:Interest) 
    WITH collect(i) as interests 
    // Check what interests are not included 
    MATCH (ni:Interest) WHERE NOT ni IN interests 
RETURN ni.name 
+0

Это умный способ! Он работает сейчас. Благодаря! – avidProgrammer

0

A WHERE непосредственно после ДОПОЛНИТЕЛЬНОГО МАТЧА Взято в оценка.

Если вы хотите отправить фильтр, вы должны использовать WITH между ними.

MATCH (u:User{userId : 1}) 
OPTIONAL MATCH (u)-[r:IS_INTERESTED] -(i:Interest) 
WITH r,i 
WHERE r is NULL 
Return i.name as interest 
+0

Я попробовал ваш ответ, и он ничего не возвращает. Он просто возвращает сообщение _ (без изменений, без строк) _ – avidProgrammer

1

Когда OPTIONAL MATCH запрос не найден, то оба r И i должны быть NULL. В конце концов, поскольку нет отношения, нет способа получить узлы, на которые он указывает.

+0

Я вижу. Так есть лучший способ (чем использовать второй запрос, который я использовал), чтобы найти интересы, не выбранные конкретным пользователем? – avidProgrammer

+0

Я не вижу лучшего способа. – cybersam

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