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 }) -> 변수는 한 트랜젼션으로 처리 해야 먹힘

술어함수

  1. 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 ->통제하기 좋네

  1. 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"]


  1. 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


  1. 없음 () MATCH p =(n)-[*1..3]->(b) WHERE n.name = 'Alice' AND NONE (x IN nodes(p) WHERE x.age = 25) RETURN p ->

  1. 싱글 () 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})


  1. coalesce () MATCH (a) WHERE a.name = 'Alice' RETURN coalesce(a.hairColor, a.eyes) ->null 빼고 첫번째 값만 표현 coalesce(a.hairColor, a.eyes) "brown"

  1. endNode () MATCH (x:Developer)-[r]-() RETURN endNode(r)

  1. 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]

  1. id () MATCH (a) RETURN id(a) -> id(a) 0 1 13 14 15

  1. last () MATCH (a) WHERE a.name = 'Eskil' RETURN a.array, last(a.array) ->head()와 반대 a.array last(a.array) ["one", "two", "three"] "three"

  1. 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"


  1. 속성 () CREATE (p:Person { name: 'Stefan', city: 'Berlin' }) RETURN properties(p) -> properties(p) { "city": "Berlin", "name": "Stefan" }

  1. randomUUID () RETURN randomUUID() AS uuid -> uuid "0800ef84-cbc7-4e20-b2c4-0fcf546e5870"

  1. size () RETURN size(['Alice', 'Bob']) -> size(['Alice', 'Bob']) 2

  1. 패턴 표현에 적용되는 size () MATCH (a) WHERE a.name = 'Alice' RETURN size((a)-->()-->()) AS fof ->패턴 표현식과 일치하는 경로 수가 반환됩니다. fof 3

  1. 문자열에 적용되는 size () MATCH (a) WHERE size(a.name)> 6 RETURN a.name, size(a.name) -> a.name size(a.name) "Charlie" 7

  1. startNode () MATCH (x:Developer)-[r]-() RETURN startNode(r)

  1. timestamp () RETURN timestamp() -> timestamp() 1609835537095

  1. toBoolean () RETURN toBoolean('TRUE'), toBoolean('not a boolean') -> toBoolean('TRUE') toBoolean('not a boolean') true null

  1. toFloat () RETURN toFloat('11.5'), toFloat('not a number') -> toFloat('11.5') toFloat('not a number') 11.5 null

  1. toInteger () RETURN toInteger('42'), toInteger('not a number') -> toInteger('42') toInteger('not a number') 42 null

  1. 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})


  1. key () MATCH (a) WHERE a.name = 'Alice' RETURN keys(a) -> keys(a) ["name", "eyes", "age"]

  1. label () MATCH (a) WHERE a.name = 'Alice' RETURN labels(a) -> labels(a) ["Developer"]

  1. nodes () MATCH p =(a)-->(b)-->(c) WHERE a.name = 'Alice' AND c.name = 'Eskil' RETURN nodes(p) ->

  1. 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] []

  1. 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

  1. relationships () MATCH p =(a)-->(b)-->(c) WHERE a.name = 'Alice' AND c.name = 'Eskil' RETURN relationships(p) ->깔끔하게 나오질 않네

  1. reverse () WITH [4923,'abc',521, NULL , 487] AS ids RETURN reverse(ids) -> reverse(ids) [487, null, 521, "abc", 4923]

  1. tail () MATCH (a) WHERE a.name = 'Eskil' RETURN a.array, tail(a.array) -> a.array tail(a.array) ["one", "two", "three"] ["two", "three"]

문자열 함수

  1. left () RETURN left('hello', 3) ->"hel"

  2. ltrim () RETURN lTrim(' hello') ->"hello", trim, rtrim도 다 되네

  3. replace () RETURN replace("hello", "l", "w") ->"hewwo"

  4. reverse () RETURN reverse('anagram') ->"margana"

  5. right () RETURN right('hello', 3) ->"llo"

  6. rtrim () RETURN rTrim('hello ') ->"hello"

  7. split () RETURN split('one,two', ',') ->["one","two"]

  8. substring () RETURN substring('hello', 1, 3), substring('hello', 2) ->"ell" "llo"

  9. toLower () RETURN toLower('HELLO') ->"hello"

  10. 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"

  11. toUpper ()

  12. trim ()