Cypher 매뉴얼 v4.2 체험기 함수부문 - sfjun/neo4j GitHub Wiki
Neo4j Cypher 매뉴얼 v4.2-function
예제생성 CREATE (a {name: 'Alice', eyes: 'brown', age: 38})-[:KNOWS]-> (c {name: 'Charlie', eyes: 'green', age: 53})-[:KNOWS]->(d {name: 'Daniel', eyes: 'brown', age: 54}), (a)-[:KNOWS]->(b {name: 'Bob', eyes: 'blue', age: 25})-[:KNOWS]->(d),(b)-[:MARRIED]->(e {array: ['one', 'two', 'three'], name: 'Eskil', eyes: 'blue', age: 41}),({ eyes: 'brown', age: 61 }) -> 변수는 한 트랜젼션으로 처리 해야 먹힘
술어함수
- all () MATCH p =(a)-[*1..3]->(b) WHERE a.name = 'Alice' AND b.name = 'Daniel' AND ALL (x IN nodes(p) WHERE x.age > 30) RETURN p ->통제하기 좋네
- any ()
MATCH (a) WHERE a.name = 'Eskil' AND ANY (x IN a.array WHERE x = 'one') RETURN a.name, a.array -> 리스트중 하나라도 a.name a.array "Eskil" ["one", "two", "three"]
- exist () MATCH (n) WHERE EXISTS (n.name) RETURN n.name AS name, EXISTS ((n)-[:MARRIED]->()) AS is_married
-> 있어면 name is_married "Alice" false "Charlie" false "Daniel" false "Bob" true "Eskil" false
MATCH (a),(b) WHERE EXISTS (a.name) AND NOT EXISTS (b.name) OPTIONAL MATCH (c:DoesNotExist) RETURN a.name AS a_name, b.name AS b_name, EXISTS (b.name) AS b_has_name, c.name AS c_name, EXISTS (c.name) AS c_has_name ORDER BY a_name, b_name, c_name LIMIT 1 -> a_name b_name b_has_name c_name c_has_name "Alice" null false null null
- 없음 () MATCH p =(n)-[*1..3]->(b) WHERE n.name = 'Alice' AND NONE (x IN nodes(p) WHERE x.age = 25) RETURN p ->
- 싱글 () MATCH p =(n)-->(b) WHERE n.name = 'Alice' AND SINGLE (var IN nodes(p) WHERE var.eyes = 'blue') RETURN p
스칼라함수
예제생성 CREATE (a:Developer {name: 'Alice', eyes: 'brown', age: 38})-[:KNOWS]-> (c {name: 'Charlie', eyes: 'green', age: 53})-[:KNOWS]->(d {name: 'Daniel', eyes: 'brown', age: 54}), (a)-[:KNOWS]->(b {name: 'Bob', eyes: 'blue', age: 25})-[:KNOWS]->(d),(b)-[:MARRIED]->(e {array: ['one', 'two', 'three'], name: 'Eskil', eyes: 'blue', age: 41})
- coalesce () MATCH (a) WHERE a.name = 'Alice' RETURN coalesce(a.hairColor, a.eyes) ->null 빼고 첫번째 값만 표현 coalesce(a.hairColor, a.eyes) "brown"
- endNode () MATCH (x:Developer)-[r]-() RETURN endNode(r)
- head () MATCH (a) WHERE a.name = 'Eskil' RETURN a.array, head(a.array) -> 아래도 동일(파이선고 유사) MATCH (a) WHERE a.name = 'Eskil' RETURN a.array, head(a.array), a.array[0]
- id () MATCH (a) RETURN id(a) -> id(a) 0 1 13 14 15
- last () MATCH (a) WHERE a.name = 'Eskil' RETURN a.array, last(a.array) ->head()와 반대 a.array last(a.array) ["one", "two", "three"] "three"
- length () MATCH p =(a)-->(b)-->(c) WHERE a.name = 'Alice' RETURN length(p) -> length(p) 2 2 2
좀더 상세하게 보면 MATCH p =(a)-->(b)-->(c) WHERE a.name = 'Alice' RETURN length(p), a.name, b.name, c.name -> length(p) a.name b.name c.name 2 "Alice" "Bob" "Eskil" 2 "Alice" "Bob" "Daniel" 2 "Alice" "Charlie" "Daniel"
- 속성 () CREATE (p:Person { name: 'Stefan', city: 'Berlin' }) RETURN properties(p) -> properties(p) { "city": "Berlin", "name": "Stefan" }
- randomUUID () RETURN randomUUID() AS uuid -> uuid "0800ef84-cbc7-4e20-b2c4-0fcf546e5870"
- size () RETURN size(['Alice', 'Bob']) -> size(['Alice', 'Bob']) 2
- 패턴 표현에 적용되는 size () MATCH (a) WHERE a.name = 'Alice' RETURN size((a)-->()-->()) AS fof ->패턴 표현식과 일치하는 경로 수가 반환됩니다. fof 3
- 문자열에 적용되는 size () MATCH (a) WHERE size(a.name)> 6 RETURN a.name, size(a.name) -> a.name size(a.name) "Charlie" 7
- startNode () MATCH (x:Developer)-[r]-() RETURN startNode(r)
- timestamp () RETURN timestamp() -> timestamp() 1609835537095
- toBoolean () RETURN toBoolean('TRUE'), toBoolean('not a boolean') -> toBoolean('TRUE') toBoolean('not a boolean') true null
- toFloat () RETURN toFloat('11.5'), toFloat('not a number') -> toFloat('11.5') toFloat('not a number') 11.5 null
- toInteger () RETURN toInteger('42'), toInteger('not a number') -> toInteger('42') toInteger('not a number') 42 null
- type () MATCH (n)-[r]->() WHERE n.name = 'Alice' RETURN type(r) -> type(r) "KNOWS" "KNOWS"
Neo.ClientError.Schema.ConstraintValidationFailed 발생시 조회 후 삭제
INDEX & CONSTRAINT https://velog.io/@eunzin/neo4j-cypher
생성: CREATE INDEX ON :Label(prop1, …, propN) CREATE INDEX ON :Person(name) 조회: CALL db.indexes 삭제: DROP INDEX ON :Label(prop1, …, propN) DROP INDEX ON :Person(name)
생성: // 레이블이 Person인 노드에 name 값을 UNIQUE한 값으로.. CREATE CONSTRAINT ON (ee:Person) ASSERT ee.name IS UNIQUE 조회: CALL db.constraints 삭제: DROP CONSTRAINT ON (ee:Person) ASSERT ee.name IS UNIQUE
constraints 조회 CALL db.constraints
name description details "constraint_3044d997" "CONSTRAINT ON ( movie:Movie ) ASSERT (movie.title) IS UNIQUE" "Constraint( id=3, name='constraint_3044d997', type='UNIQUENESS', schema=(:Movie {title}), ownedIndex=2 )" "constraint_e26b1a8b" "CONSTRAINT ON ( person:Person ) ASSERT (person.name) IS UNIQUE" "Constraint( id=5, name='constraint_e26b1a8b', type='UNIQUENESS', schema=(:Person {name}), ownedIndex=4 )" "constraint_fd6fb336" "CONSTRAINT ON ( person:Person ) ASSERT (person.role) IS UNIQUE" "Constraint( id=7, name='constraint_fd6fb336', type='UNIQUENESS', schema=(:Person {role}), ownedIndex=6 )"
위 DESCRIPTION에 DROP 하면됨 DROP CONSTRAINT ON ( movie:Movie ) ASSERT (movie.title) IS UNIQUE
Aggregating functions
CREATE (a:Person { name: 'A', age: 13 })-[:KNOWS]->(b:Person { name: 'B', age: 33, eyes: 'blue' })-[:KNOWS]->(e:Person { name: 'D' }), (a)-[:KNOWS]->(c:Person { name: 'C', age: 44, eyes: 'blue'})-[:KNOWS]->(e),(a)-[:KNOWS]->(d:Person { name: 'D', eyes: 'brown' })
4.1. count()노드 수를 반환하는 데 사용 MATCH (n { name: 'A' })-->(x) RETURN labels(n), n.age, count() -> labels(n) n.age count(*) ["Person"] 13 3
4.2. count()관계 유형을 그룹화하고 계산하는 데 사용 MATCH (n { name: 'A' })-[r]->() RETURN type(r), count() -> type(r) count(*) "KNOWS" 3
4.3. count(expression)값 수를 반환하는 데 사용 MATCH (n { name: 'A' })-->(x) RETURN count(x) -> count(x) 3
4.5. 중복 유무에 관계없이 계산 MATCH (me:Person)-->(friend:Person)-->(friend_of_friend:Person) WHERE me.name = 'A' RETURN count(DISTINCT friend_of_friend), count(friend_of_friend) -> count(DISTINCT friend_of_friend) count(friend_of_friend) 1 2
LIST
CREATE (a:Developer {name: 'Alice', eyes: 'brown', age: 38})-[:KNOWS]-> (c {name: 'Charlie', eyes: 'green', age: 53})-[:KNOWS]->(d {name: 'Daniel', eyes: 'brown', age: 54}), (a)-[:KNOWS]->(b {name: 'Bob', eyes: 'blue', age: 25})-[:KNOWS]->(d),(b)-[:MARRIED]->(e {array: ['one', 'two', 'three'], name: 'Eskil', eyes: 'blue', age: 41})
- key () MATCH (a) WHERE a.name = 'Alice' RETURN keys(a) -> keys(a) ["name", "eyes", "age"]
- label () MATCH (a) WHERE a.name = 'Alice' RETURN labels(a) -> labels(a) ["Developer"]
- nodes () MATCH p =(a)-->(b)-->(c) WHERE a.name = 'Alice' AND c.name = 'Eskil' RETURN nodes(p) ->
- range () RETURN range(0, 10), range(2, 18, 3), range(0, 5, -1) -> range(0, 10) range(2, 18, 3) range(0, 5, -1) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [2, 5, 8, 11, 14, 17] []
- reduce () MATCH p =(a)-->(b)-->(c) WHERE a.name = 'Alice' AND b.name = 'Bob' AND c.name = 'Daniel' RETURN reduce(totalAge = 0, n IN nodes(p)| totalAge + n.age) AS reduction -> reduction 117
- relationships () MATCH p =(a)-->(b)-->(c) WHERE a.name = 'Alice' AND c.name = 'Eskil' RETURN relationships(p) ->깔끔하게 나오질 않네
- reverse () WITH [4923,'abc',521, NULL , 487] AS ids RETURN reverse(ids) -> reverse(ids) [487, null, 521, "abc", 4923]
- tail () MATCH (a) WHERE a.name = 'Eskil' RETURN a.array, tail(a.array) -> a.array tail(a.array) ["one", "two", "three"] ["two", "three"]
문자열 함수
-
left () RETURN left('hello', 3) ->"hel"
-
ltrim () RETURN lTrim(' hello') ->"hello", trim, rtrim도 다 되네
-
replace () RETURN replace("hello", "l", "w") ->"hewwo"
-
reverse () RETURN reverse('anagram') ->"margana"
-
right () RETURN right('hello', 3) ->"llo"
-
rtrim () RETURN rTrim('hello ') ->"hello"
-
split () RETURN split('one,two', ',') ->["one","two"]
-
substring () RETURN substring('hello', 1, 3), substring('hello', 2) ->"ell" "llo"
-
toLower () RETURN toLower('HELLO') ->"hello"
-
toString () RETURN toString(11.5), toString('already a string'), toString(TRUE ), toString(date({ year:1984, month:10, day:11 })) AS dateString, toString(datetime({ year:1984, month:10, day:11, hour:12, minute:31, second:14, millisecond: 341, timezone: 'Europe/Stockholm' })) AS datetimeString, toString(duration({ minutes: 12, seconds: -60 })) AS durationString -> toString(11.5) toString('already a string') toString(TRUE ) dateString datetimeString durationString "11.5" "already a string" "true" "1984-10-11" "1984-10-11T12:31:14.341+01:00[Europe/Stockholm]" "PT11M"
-
toUpper ()
-
trim ()