조건 함수#
예·아니요로 답하는 함수들입니다. 리스트 수량자 네 개, all·any·none·single은 평범한 호출이
아니라 문법 형태입니다. 각각 변수, 리스트, WHERE 절을 받습니다. 각각 요소별 결과를 삼치 논리로
줄이므로, null을 담은 리스트는 답을 거짓이 아니라 null로 만들 수 있습니다.
예제는 예제 데이터셋에서 실행됩니다.
all#
all ( variable IN list WHERE predicate ) -> boolean
리스트의 모든 요소에 대해 조건이 성립하면 참을 반환합니다.
고려할 점
빈 리스트는 참을 반환합니다.
어떤 요소에서 조건이 null이고 나머지 전부에서 참이면 결과는 null입니다. 거짓인 요소가 하나 있으면 다른 것이 null이든 결과는 거짓입니다.
조건은 모든 요소에 대해 평가되며, 조기에 끊는 것이 없습니다.
이 호출은
cypher_all()로 컴파일됩니다. 조건 안에서 나온 오류 메시지에는 그 이름이 실립니다.
MATCH (m:movie) WHERE all(x IN m.embedding WHERE x > -0.1) RETURN m.title ORDER BY m.title;
title
---------------------
"Blade Runner 2049"
any#
any ( variable IN list WHERE predicate ) -> boolean
리스트의 요소 중 적어도 하나에 대해 조건이 성립하면 참을 반환합니다.
고려할 점
빈 리스트는 거짓을 반환합니다.
참인 요소가 하나 있으면 다른 요소가 null이어도 결과는 참입니다.
참인 요소가 없고 null인 것이 하나라도 있으면 결과는 null입니다.
MATCH (p:person)-[:acted_in]->(m:movie)
WITH p, collect(m.genre) AS genres
WHERE any(g IN genres WHERE g = 'Adventure')
RETURN p.name AS actor;
actor
-------------
"Sam Neill"
exists#
exists ( pattern ) -> boolean
exists ( property_reference ) -> boolean
패턴을 주면 그 패턴이 적어도 한 번 일치할 때 참을 반환합니다. 속성 참조를 주면 그 속성이 있고 null이 아닐 때 참을 반환합니다.
고려할 점
두 형태는 하나의 함수의 오버로드가 아니라 서로 다른 구문입니다. 패턴 형태는
EXISTS서브쿼리가 되고, 속성 형태는IS NOT NULL검사가 됩니다.속성 형태의 인자는
m.year같은 속성 참조여야 합니다. 임의의 표현식은 패턴으로 읽혀 파싱에 실패합니다.exists()안의 패턴은 아래의(p)처럼 감싸는 쿼리의 변수를 바인딩할 수 있지만, 그것이 도입하는 변수는 밖에서 보이지 않습니다.
MATCH (m:movie {title:'Inception'}) RETURN exists(m.year) AS has_year, exists(m.budget) AS has_budget;
has_year | has_budget
----------+------------
t | f
MATCH (p:person) WHERE exists((p)-[:directed]->()) RETURN p.name ORDER BY p.name LIMIT 3;
name
---------------------
"Andrew Niccol"
"Christopher Nolan"
"Denis Villeneuve"
isEmpty#
isEmpty ( value jsonb ) -> boolean
리스트에 요소가 없거나 맵에 키가 없으면 참을 반환합니다.
고려할 점
인자는
jsonb로 해석돼야 합니다. 문자열 리터럴만 쓰면 그것은unknown이고 range·multirange의isempty에도 일치합니다:
RETURN isEmpty('');
ERROR: function isempty(unknown) is not unique
LINE 1: RETURN isEmpty('');
^
HINT: Could not choose a best candidate function. You might need to add explicit type casts.
형 변환을 하십시오: isEmpty(''::jsonb).
속성 참조는 이미
jsonb이므로isEmpty(n.tags)에는 형 변환이 필요하지 않습니다.빈 문자열에 대해 참을 반환합니다. 그것이 빈
jsonb스칼라입니다.
RETURN isEmpty([]) AS empty_list, isEmpty([1]) AS one_element, isEmpty({}) AS empty_map;
empty_list | one_element | empty_map
------------+-------------+-----------
t | f | t
none#
none ( variable IN list WHERE predicate ) -> boolean
리스트의 어떤 요소에 대해서도 조건이 성립하지 않으면 참을 반환합니다.
any의 부정입니다.
고려할 점
빈 리스트는 참을 반환합니다.
참인 요소가 하나 있으면 결과는 거짓입니다. 참인 요소가 없고 null인 것이 하나라도 있으면 결과는 null입니다.
MATCH (m:movie) WHERE none(x IN m.embedding WHERE x > 0.4) RETURN count(*) AS films;
films
-------
15
single#
single ( variable IN list WHERE predicate ) -> boolean
리스트의 요소 중 정확히 하나에 대해 조건이 성립하면 참을 반환합니다.
고려할 점
빈 리스트는 거짓을 반환합니다.
어떤 요소에서든 결과가 null이면 답 전체가 null입니다. 그 null이 두 번째 일치였을 수도 있기 때문입니다.
MATCH (p:person)-[:directed]->(m:movie)
WITH p, collect(m.year) AS years
WHERE single(y IN years WHERE y > 2010)
RETURN p.name AS director, years ORDER BY p.name;
director | years
---------------------+--------------------------
"Christopher Nolan" | [2010, 2014]
"Denis Villeneuve" | [2017]
"Joss Whedon" | [2012]
"Lana Wachowski" | [2003, 1999, 2021, 2003]
"Neill Blomkamp" | [2013]
삼치 결과 나란히 보기#
수량자들의 차이는 리스트가 null을 담고 있을 때와 리스트가 비어 있을 때 가장 크게 드러납니다. 아래 두 행은 실제 출력입니다:
RETURN all(x IN [1, null] WHERE x > 0) AS every, any(x IN [1, null] WHERE x > 0) AS some,
none(x IN [null] WHERE x > 0) AS not_any, single(x IN [1, null] WHERE x > 0) AS exactly_one;
every | some | not_any | exactly_one
-------+------+---------+-------------
| t | |
RETURN all(x IN [] WHERE x = 0) AS every, any(x IN [] WHERE x = 0) AS some,
none(x IN [] WHERE x = 0) AS not_any, single(x IN [] WHERE x = 0) AS exactly_one;
every | some | not_any | exactly_one
-------+------+---------+-------------
t | f | t | f
RETURN은 불리언 컬럼을 jsonb로 감싸지 않고 boolean으로 둡니다. 그래서 이것들은 true·false·
null이 아니라 t·f와 null에 해당하는 빈 칸으로 출력됩니다.
호환성#
openCypher#
속성에 대한 exists()는 IS NOT NULL의 openCypher 옛 표기입니다. 패턴 컴프리헨션과
exists { ... } 블록 형태는 지원되지 않습니다. 위의 패턴 형태나
서브쿼리 표현식을 쓰십시오.