Подтвердить что ты не робот

Вернуть node если отношения нет

Я пытаюсь создать запрос с использованием cypher, который будет "обнаруживать" недостающие компоненты, которые может иметь шеф-повар. Мой график настроен так:

(ingredient_value)-[:is_part_of]->(ingredient)

(ingredient) будет иметь ключ/значение name= "цветов красителя". (ingredient_value) может иметь ключ/значение значения = "красный" и "является частью" (ingredient, name="dye colors").

(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)

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

(chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)<-[:has_ingredient*0..0]-chef

но это ничего не вернуло.

Является ли это чем-то, что может быть выполнено cypher/neo4j, или это то, что лучше всего обрабатывать, возвращая все ингредиенты и самостоятельно сортируя их?

Бонус: Также есть способ использовать cypher для соответствия всем значениям, которые повар имеет для всех значений, которые требуется рецепту. Пока что я вернул все частичные совпадения, возвращаемые chef-[:has_value]->ingredient_value<-[:requires_value]-recipe и агрегируя результаты самостоятельно.

4b9b3361

Ответ 1

Обновление 01/10/2013:

Переместился через ссылку Neo4j 2.0:

Старайтесь не использовать дополнительные отношения. Прежде всего,

не использовать их следующим образом:

MATCH a-[r?:LOVES]->() WHERE r IS NULL, где вы просто убедитесь, что они не существуют.

Вместо этого сделайте следующее:

MATCH a WHERE NOT (a)-[:LOVES]->()

Использование cypher для проверки того, не существует ли отношения:

...
MATCH source-[r?:someType]-target
WHERE r is null
RETURN source

Что? mark делает связь необязательной.

ИЛИ

В neo4j 2 do:

...
OPTIONAL MATCH source-[r:someType]-target
WHERE r is null
RETURN source

Теперь вы можете проверить наличие несуществующих (нулевых) отношений.

Ответ 2

Для выборки узлов, не имеющих отношения

Это хороший вариант проверки отношения существует или нет

MATCH (player)-[r:played]->()
    WHERE r IS NULL 
    RETURN player

Вы также можете проверить несколько условий для этого Он вернет все узлы, которые не имеют "сыгранных" или "незаложенных" отношений.

MATCH (player) 
 WHERE NOT (player)-[:played|notPlayed]->()
 RETURN player

Получить узлы, которые не имеют никакой реальности

MATCH (player) 
WHERE NOT (player)-[r]-()
RETURN player

Он проверит node отсутствие входящих/исходящих отношений.

Ответ 3

Если вам нужна семантика условного исключения, вы можете достичь этого таким образом.

Как и в случае с neo4j 2.2.1, вы можете использовать предложение OPTIONAL MATCH и фильтровать непревзойденные (NULL) узлы.

Также важно использовать предложение WITH между предложениями OPTIONAL MATCH и WHERE, так что WHERE ведет себя как фильтр, а не как часть шаблона соответствия.

Предполагая, что у нас есть 2 типа узлов: Person и Communication. Если я хочу получить все Лица, которые никогда не общались по телефону, но, возможно, обменивались другими способами, я бы сделал этот запрос:

MATCH (p: Person) 
OPTIONAL MATCH p--(c: Communication) 
WHERE c.way = 'telephone'
WITH p, c 
WHERE c IS NULL 
RETURN p

Обратите внимание, что первое предложение WHERE ведет себя точно так же, как часть соответствия.

Литература:

http://neo4j.com/docs/stable/query-optional-match.html#_introduction_3 http://java.dzone.com/articles/new-neo4j-optional

Ответ 4

Я выполнил эту задачу, используя гремлин. Я сделал

x=[]

g.idx('Chef')[[name:'chef1']].as('chef')
.out('has_ingredient').as('alreadyHas').aggregate(x).back('chef')
.out('has_value').as('values')
.in('requires_value').as('recipes')
.out('requires_ingredient').as('ingredients').except(x).path()

Это вернуло пути всех недостающих ингредиентов. Я не смог сформулировать это на языке cypher, по крайней мере, для версии 1.7.

Ответ 5

Я написал суть, показывающую, как это можно сделать вполне естественно, используя Cypher 2.0

http://gist.neo4j.org/?9171581

Ключевым моментом является использование опционального соответствия доступным ингредиентам, а затем сравнение с фильтрами для отсутствующих (нулевых) ингредиентов или ингредиентов с неправильным значением.

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

Ответ 6

Последний запрос должен быть:

START chef = node(..)
MATCH (chef)-[:has_value]->(ingredient_value)<-[:requires_value]-(recipe)-[:requires_ingredient]->(ingredient)
WHERE (ingredient)<-[:has_ingredient]-chef
RETURN ingredient

Этот шаблон: (ingredient)<-[:has_ingredient*0..0]-chef

Является ли причина, по которой она ничего не вернула. *0..0 означает, что длина отношений должна быть равна нулю, а это означает, что ингредиент и шеф-повар должны быть одинаковыми node, которых они не являются.