요리사가 가질 수있는 누락 된 재료를 “찾기”하는 cypher를 사용하여 쿼리를 만들려고합니다. 내 그래프는 다음과 같이 설정됩니다.
(ingredient_value)-[:is_part_of]->(ingredient)
(ingredient)
키 / 값은 name = “dye colors”입니다. (ingredient_value)
key / value는 value = “red”이고 “is part of”일 수 (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를 사용하는 방법이 있습니다. 지금까지 a에 의해 반환 된 모든 부분 일치 만 반환 chef-[:has_value]->ingredient_value<-[:requires_value]-recipe
하고 결과를 직접 집계했습니다.
답변
2013 년 1 월 10 일 업데이트 :
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
? 마크는 관계를 선택적으로 만듭니다.
또는
neo4j 2에서 다음을 수행하십시오.
...
OPTIONAL MATCH source-[r:someType]-target
WHERE r is null
RETURN source
이제 존재하지 않는 (null) 관계를 확인할 수 있습니다.
답변
관계가없는 노드를 가져 오는 경우
관계가 있는지 여부를 확인하는 좋은 옵션입니다.
MATCH (player)
WHERE NOT(player)-[:played]->()
RETURN player
이에 대한 여러 조건을 확인할 수도 있습니다. “played”또는 “notPlayed”관계가없는 모든 노드를 반환합니다.
MATCH (player)
WHERE NOT (player)-[:played|notPlayed]->()
RETURN player
실현성이없는 노드를 가져 오려면
MATCH (player)
WHERE NOT (player)-[r]-()
RETURN player
들어오는 / 나가는 관계가없는 노드를 확인합니다.
답변
“조건부 제외”의미 체계가 필요한 경우이 방법을 사용할 수 있습니다.
neo4j 2.2.1부터 OPTIONAL MATCH
절 을 사용 하여 일치하지 않는 ( NULL
) 노드를 필터링 할 수 있습니다 .
사용하는 것도 중요하다 WITH
사이 절 OPTIONAL MATCH
과 WHERE
, 절을 그래서 먼저 WHERE
정의하는 옵션 일치 조건과 두 번째 WHERE
필터처럼 동작합니다.
두 가지 유형의 노드가 있다고 가정합니다. Person
및 Communication
. 전화로 통신 한 적이 없지만 다른 방식으로 통신했을 수있는 모든 사람을 얻으려면 다음 쿼리를 작성합니다.
MATCH (p: Person)
OPTIONAL MATCH p--(c: Communication)
WHERE c.way = 'telephone'
WITH p, c
WHERE c IS NULL
RETURN p
경기 패턴은 통신을 가진 모든 사람과 일치합니다 c
것 NULL
이외의 전화 통신을합니다. 그런 다음 필터 ( WHERE
후 WITH
)는 다른 모든 전화 통신을 필터링합니다.
참조 :
http://neo4j.com/docs/stable/query-optional-match.html#_introduction_3
http://java.dzone.com/articles/new-neo4j-optional
답변
Cypher 2.0을 사용하여 이것이 어떻게 자연스럽게 이루어질 수 있는지 보여주는 요점을 작성했습니다.
http://gist.neo4j.org/?9171581
요점은 사용 가능한 재료에 대한 선택적 일치를 사용한 다음 누락 된 (null) 재료 또는 잘못된 값을 가진 재료를 필터링하기 위해 비교하는 것입니다.
개념은 선언적이며 알고리즘을 설명 할 필요가 없으며 필요한 것을 적어두면됩니다.
답변
나는 gremlin을 사용하여이 작업을 완료했습니다. 나는했다
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()
이것은 모든 누락 된 재료의 경로를 반환했습니다. 나는 적어도 1.7 버전에서는 이것을 사이퍼 언어로 공식화 할 수 없었다.
답변
마지막 쿼리는 다음과 같아야합니다.
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
관계의 길이가 0이어야 함을 의미합니다. 즉, 재료와 요리사는 동일한 노드 여야하지만 그렇지 않습니다.