관계가없는 경우 노드 반환


90

요리사가 가질 수있는 누락 된 재료를 "찾기"하는 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하고 결과를 직접 집계했습니다.


v3 관련 정보는 여기에서 확인하십시오. stackoverflow.com/questions/25673223/…
— Maciej

향후 사용자를 위해; 자세한 내용은 neo4j.com/developer/subqueries/#existential-subqueries 절 exists에서 사용할 수 있습니다 . WHERE
— ozanmuyes

답변:


159

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) 관계를 확인할 수 있습니다.


3
Neo4j 2.0에서는 사용 OPTIONAL MATCH는 첫 번째 예는 선택 사양 MATCH (소스)과 같을 것이다, 즉 선택적인 관계를 일치 - [R : someType] - (대상) RETURN 소스를, R은
— 머뭇 거리는

WHERE NOT에 레이블이 지정된 노드를 사용하려고하는데 작동하지 않습니다. Like : MATCH a WHERE NOT (a)-[: LOVES]-> (Stranger),이 'Stranger'는 노드 레이블입니다. 저는 neo4j 버전 2.1.2를 사용하고 있습니다
— Krishna Shetty

1
신경
— 쓰지

4
MATCH a...예를 지금해야MATCH (a) WHERE NOT (a)-[:LOVES]->()
— 리암

1
@ gil-stal 왜 이런 쿼리에 노드 이름을 사용할 수 없습니까? WHERE NOT (a)-[: LOVES]-> (b : SomeLabel)와 일치합니다. 노드 이름을 사용하지 않으면 작동합니다.
— iit2011081

15

관계가없는 노드를 가져 오는 경우

관계가 있는지 여부를 확인하는 좋은 옵션입니다.

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

들어오는 / 나가는 관계가없는 노드를 확인합니다.


4
MATCH (player) WHERE NOT (player)-[r]-() RETURN player 주는 변수 R 정의되지 않았습니다 오류입니다. r을 어떻게 정의 할 수 있습니까?
— Chathura Wijeweera

이 문제를 해결하려면 관계 (예 (player -[:rel]- ()(player -[]- ()
— :)

MATCH (player) WHERE NOT (player)-[]-() RETURN player-잘 작동합니다
— Prashanth Terala

첫 번째 쿼리는 실제로 잘못되었습니다. MATCH 패턴 자체는 항상 기존 관계 만 반환하고 NULL은 반환하지 않습니다. 따라서 WHERE 라인에는 필터링 할 항목이 없습니다.
— Cristi S.

@CristiS. 알려 줘서 고마워. 작동해야하는 쿼리를 업데이트했습니다
— Satish Shinde

8

"조건부 제외"의미 체계가 필요한 경우이 방법을 사용할 수 있습니다.

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


2

Cypher 2.0을 사용하여 이것이 어떻게 자연스럽게 이루어질 수 있는지 보여주는 요점을 작성했습니다.

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

요점은 사용 가능한 재료에 대한 선택적 일치를 사용한 다음 누락 된 (null) 재료 또는 잘못된 값을 가진 재료를 필터링하기 위해 비교하는 것입니다.

개념은 선언적이며 알고리즘을 설명 할 필요가 없으며 필요한 것을 적어두면됩니다.


2

나는 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 버전에서는 이것을 사이퍼 언어로 공식화 할 수 없었다.


2

마지막 쿼리는 다음과 같아야합니다.

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이어야 함을 의미합니다. 즉, 재료와 요리사는 동일한 노드 여야하지만 그렇지 않습니다.


예, 그러나 원하는 재료를 반환하지 않습니다. 요리사가 이미 조리법과 공통점을 가지고있는 것을 반환합니다. 차이점을 알고 싶습니다.
— Nicholas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.