jsonb 연산자와 함수#
속성은 jsonb입니다. 정점은 복합 타입 (id graphid, properties jsonb)이고, 간선에는 start와
end가 더해집니다. 그러므로 Cypher에서 읽는 모든 속성과 SQL에서 손대는 모든 속성 컬럼이
PostgreSQL jsonb 타입의 값입니다. 이 페이지의 다른 무엇보다 먼저 받아들여야 할 결과가 두
가지입니다. 문자열 속성은 따옴표와 함께 돌아오고, jsonb 연산자 전체가 그것에 적용됩니다.
예제는 예제 데이터셋에서 실행됩니다.
속성 접근 연산자#
이 네 개는 왼쪽에 jsonb 값을 받습니다. 화살표가 겹친 둘은 text를 반환하고, 화살표가 하나인
둘은 jsonb를 반환합니다.
연산자 |
오른쪽 피연산자 |
반환 타입 |
결과 |
|---|---|---|---|
|
|
|
그 키나 인덱스에 있는 값 |
|
|
|
같은 값이며, 문자열은 따옴표가 벗겨진 상태 |
|
|
|
그 경로에 있는 값 |
|
|
|
같은 값이며, 문자열은 따옴표가 벗겨진 상태 |
SELECT properties -> 'name' AS quoted, properties ->> 'name' AS plain
FROM moviekb.person ORDER BY id LIMIT 1;
quoted | plain
----------------+--------------
"Keanu Reeves" | Keanu Reeves
SELECT '{"a":{"b":[1,2]}}'::jsonb #> '{a,b}' AS at_path,
'{"a":{"b":[1,2]}}'::jsonb #>> '{a,b,0}' AS at_path_text;
at_path | at_path_text
---------+--------------
[1, 2] | 1
따옴표 없는 스칼라로 꺼내기#
Cypher의 RETURN은 스칼라 출력 컬럼을 jsonb로 감쌉니다. 그래서 RETURN m.title은 따옴표까지
포함해 "Inception"을 출력하고, RETURN m.title::text도 그렇습니다. 그 따옴표는 psql이 만든
것이 아니라 JSON의 일부입니다.
빠져나가는 길은 #>> '{}'입니다. 빈 경로가 문서 전체를 고르고, #>>이 그것을 text로
반환합니다. Cypher를 SQL로 감싸고 거기서 적용하십시오:
SELECT t AS boxed, t #>> '{}' AS unboxed
FROM (MATCH (m:movie {title:'Inception'}) RETURN m.title AS t) q;
boxed | unboxed
-------------+-----------
"Inception" | Inception
Cypher 결과를 평범한 text와 조인하거나 비교해야 할 때는 언제든 이 관용구를 꺼내 쓰십시오.
관계형 테이블과의 조인이 그런 경우입니다.
포함·존재 연산자#
연산자 |
오른쪽 피연산자 |
참이 되는 조건 |
|---|---|---|
|
|
왼쪽 문서가 오른쪽 문서를 포함할 때 |
|
|
왼쪽 문서가 오른쪽 문서에 포함될 때 |
|
|
그 키나 문자열 요소가 있을 때 |
`? |
` |
|
|
|
그 키가 모두 있을 때 |
SELECT properties @> '{"name":"Keanu Reeves"}' AS contains,
properties ? 'born' AS has_born,
properties ?& ARRAY['name','born'] AS has_both
FROM moviekb.person ORDER BY id LIMIT 1;
contains | has_born | has_both
----------+----------+----------
t | t | t
속성 인덱스는 이 중 어느 것도 처리할 수 없습니다. 각각 키 하나와의 비교가 아니라 properties 전체에
대한 포함 검사이기 때문입니다. properties에 걸린 GIN 인덱스는 처리할 수 있습니다.
변경 연산자#
연산자 |
오른쪽 피연산자 |
결과 |
|---|---|---|
|
|
두 문서를 병합한 것이며, 공유된 키에서는 오른쪽이 이깁니다 |
|
|
그 키나 요소가 빠진 문서 |
|
|
그 경로의 값이 빠진 문서 |
SELECT '{"a":1}'::jsonb || '{"b":2}'::jsonb AS merged,
'{"a":1,"b":2}'::jsonb - 'a' AS without_a,
'{"a":{"b":1}}'::jsonb #- '{a,b}' AS without_path;
merged | without_a | without_path
------------------+-----------+--------------
{"a": 1, "b": 2} | {"b": 2} | {"a": {}}
Cypher에서는 이것들을 대신 절로 표기합니다. SET n += {city:'Seoul'}이 병합하고
REMOVE n.city가 키를 지웁니다.
jsonb에 대한 산술 연산자#
PostgreSQL이 이미 jsonb에 대해 -와 ||에 뜻을 주었으므로, AgensGraph는 그것을 산술에 다시 쓸
수 없었습니다. 그래서 이름을 백틱으로 감싼 연산자 여덟 개를 더했습니다. 속성에 +, -, *, /,
%, ^를 쓰면 Cypher 파서가 그것들을 내놓습니다.
연산자 |
구현 함수 |
OID |
뜻 |
|---|---|---|---|
|
|
7176 |
덧셈. 문자열 둘이나 리스트 둘이면 이어 붙이기 |
|
|
7178 |
뺄셈 |
|
|
7180 |
곱셈 |
|
|
7182 |
나눗셈. 두 피연산자가 모두 정수면 정수 나눗셈 |
|
|
7184 |
나머지 |
|
|
7186 |
거듭제곱 |
|
|
7190 |
단항 플러스 |
|
|
7191 |
단항 마이너스 |
이 포크의 렉서에서 백틱은 연산자 문자이므로(scan.l:369), 이 이름들은 SQL에서도 입력할 수
있습니다. 두 피연산자 모두 jsonb여야 합니다:
SELECT '"a"'::jsonb `+` '"b"'::jsonb AS strings, '[1]'::jsonb `+` '[2]'::jsonb AS lists;
strings | lists
---------+--------
"ab" | [1, 2]
참고
Cypher의 산술은 평범한 연산자로 쓰고 — n.a + n.b — 파서가 이것들을 고르게 하십시오. 백틱 이름이
여기 있는 것은 EXPLAIN 계획이나 오류 메시지, pg_operator 목록에서 그것을 알아볼 수 있게 하려는
것입니다. 구현 함수를 직접 호출할 수도 있습니다. jsonb_add('1'::jsonb, '2'::jsonb)은 3을
반환합니다.
ag_property_text#
2.18에 추가
ag_property_text ( properties jsonb, key text, expected_kind "char" ) -> text
속성의 값을 text로 반환하지만, 저장된 값이 요구한 JSON 종류일 때만 그렇습니다.
이름 |
타입 |
설명 |
|---|---|---|
|
|
읽을 속성 맵입니다. |
|
|
속성의 이름입니다. |
|
|
숫자는 |
고려할 점
이 함수가 타입 컬럼 속성 승격의 뒤를 받칩니다.
->>은 값의 텍스트를 반환하고 텍스트에는 종류가 없으므로, 그것을 통해서는 문자열"5"와 숫자5를 구별할 수 없습니다. 정수 컬럼이라면 문자열을 담은 속성에 대해 5라고 답해 버립니다. 이 함수는 종류를 먼저 묻습니다.종류가 맞지 않으면 null을 반환하는 것이 아니라 오류를 냅니다.
property "n" holds a number가 나오고 상세로A column promoting this property holds strings.가 따라옵니다.없는 속성, 또는 있으면서 JSON null인 속성은 null을 반환합니다.
손으로 쓰도록 만든 함수가 아닙니다. 속성은 Cypher에서
n.key로, SQL에서properties ->> 'key'로 읽으십시오.
SELECT ag_property_text('{"name":"x","n":5}'::jsonb, 'n', 'n') AS number,
ag_property_text('{"name":"x"}'::jsonb, 'missing', 's') AS absent;
number | absent
--------+--------
5 |
cypher_to_jsonb#
cypher_to_jsonb ( value anyelement ) -> jsonb
Cypher의 규칙으로 값을 jsonb로 감쌉니다. 그 규칙은 문자열 타입에 대해 to_jsonb의 규칙과
다릅니다.
고려할 점
Cypher의
RETURN이 스칼라 출력 컬럼을 감쌀 때 넣는 함수가 이것입니다. 실행 계획에서 그 감싸기가 일어나는 지점에 나타납니다.엄격 함수이므로 null은 null로 남습니다.
파서는 그래프 요소를 이 함수로 감싸기를 거부합니다. 그 거부 때문에
coalesce(m, 0)과 정점을 담은jsonb리스트가 실패합니다. 그 거부는 함수가 아니라 파서의coerce_to_jsonb()에 있습니다.vertex에 대해 이름으로 직접 호출하면 이 함수는id와tid까지 포함한 복합 타입 전체를 반환하며, 그것은v::jsonb가 주는properties가 아닙니다. 그것을 원하면vertex_to_jsonb나 형 변환을 쓰십시오.
SELECT cypher_to_jsonb('abc'::text) AS from_text, cypher_to_jsonb(42) AS from_integer;
from_text | from_integer
-----------+--------------
"abc" | 42
edge_to_jsonb#
edge_to_jsonb ( e edge ) -> jsonb
간선의 properties를 반환합니다. 형 변환 e::jsonb가 쓰는 함수가 이것이고,
properties(e)와 같은 값을 반환합니다.
고려할 점
MATCH ()-[e:related_to]->() WITH e LIMIT 1 RETURN edge_to_jsonb(e) AS bag;
bag
---------------
{"weight": 1}
graphid_in_jsonb_array#
graphid_in_jsonb_array ( id graphid, elements jsonb ) -> boolean
graphid가 jsonb 배열에 담긴 그래프 요소 중 하나이면 참을 반환합니다.
고려할 점
파서가
id(n) IN [...]에 대해 이 함수를 내놓아서, 요소 목록을 하나하나 벗겨 내지 않고도 검사할 수 있게 합니다.graphid는jsonb문자열로 감싸이고, 이 함수는 그 형태와 비교합니다.손으로 쓰면 평범한 소속 검사입니다.
SELECT graphid_in_jsonb_array('4.1'::graphid, '["4.1","4.2"]'::jsonb) AS present;
present
---------
t
jsonb_array_length#
jsonb_array_length ( list jsonb ) -> integer
jsonb 배열의 요소 개수를 integer로 반환합니다.
고려할 점
PostgreSQL 자신의 함수입니다.
cardinality와length가 Cypher 쪽 표기이고jsonb를 반환합니다. 이 함수는 네이티브integer를 반환하고, 배열이 아닌 값에 대해서는 오류를 냅니다.
SELECT jsonb_array_length('[1,2,3]');
jsonb_array_length
--------------------
3
to_jsonb#
to_jsonb ( value anyelement ) -> jsonb
어떤 SQL 값이든 jsonb로 변환하며, 복합 타입은 객체로, 배열은 배열로 대응시킵니다.
고려할 점
관계형 행을 그래프로 들여오는 방법이 이것입니다.
LOAD FROM t AS r CREATE (:label = to_jsonb(row_to_json(r)))가 각 행을properties로 바꿉니다.그래프 요소에 대해서는
properties가 아니라 복합 타입 전체를 변환합니다.properties를 주는 것은v::jsonb와vertex_to_jsonb입니다.
SELECT to_jsonb(42) AS number, to_jsonb('x'::text) AS string;
number | string
--------+--------
42 | "x"
vertex_to_jsonb#
vertex_to_jsonb ( v vertex ) -> jsonb
정점의 properties를 반환합니다. 형 변환 v::jsonb가 쓰는 함수가 이것이고,
properties(v)와 같은 값을 반환합니다.
MATCH (n:person {name:'Keanu Reeves'}) RETURN vertex_to_jsonb(n) AS bag;
bag
----------------------------------------
{"born": 1964, "name": "Keanu Reeves"}
순서와 비교#
jsonb에는 자기만의 전순서가 있고, 그것은 값들이 자기 타입에서 가질 순서가 아닙니다. 종류가 먼저
옵니다. null, 그다음 문자열, 그다음 숫자, 그다음 불리언, 그다음 배열, 그다음 객체입니다. 같은 종류의
값만 값으로 비교됩니다:
SELECT v FROM (VALUES ('1'::jsonb),('"a"'),('true'),('null'),('[1]'),('{"k":1}')) t(v) ORDER BY v;
v
----------
null
"a"
1
true
[1]
{"k": 1}
Cypher 결과를 정렬하거나 집계하는 곳이면 어디서나 이것이 문제가 됩니다. jsonb 컬럼에 대한
min()과 max()가 그 순서를 따르므로, 어떤 행에서는 숫자를 담고 어떤 행에서는 문자열을 담는
속성은 읽는 사람이 기대하는 대로 정렬되지 않습니다. 순서가 그 타입 자신의 것이어야 한다면 타입
컬럼을 통해 읽거나 형 변환을 하십시오.
정수 둘도 정수로 나뉩니다. jsonb가 그 구별을 유지하기 때문입니다:
RETURN 7 / 2 AS integer_division, 7.0 / 2 AS real_division;
integer_division | real_division
------------------+--------------------
3 | 3.5000000000000000
관련 항목#
모든 함수 — 모든 함수를 한 표에
스칼라 함수 —
properties,keys,length타입 변환 함수 —
to…계열SQL과 Cypher 섞기 —
#>> '{}'이 값어치를 하는 곳