관계가없는 경우 노드 반환


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-subqueriesexists에서 사용할 수 있습니다 . 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 MATCHWHERE, 절을 그래서 먼저 WHERE정의하는 옵션 일치 조건과 두 번째 WHERE필터처럼 동작합니다.

두 가지 유형의 노드가 있다고 가정합니다. PersonCommunication. 전화로 통신 한 적이 없지만 다른 방식으로 통신했을 수있는 모든 사람을 얻으려면 다음 쿼리를 작성합니다.

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

경기 패턴은 통신을 가진 모든 사람과 일치합니다 cNULL이외의 전화 통신을합니다. 그런 다음 필터 ( WHEREWITH)는 다른 모든 전화 통신을 필터링합니다.

참조 :

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.