--- language: cypher filename: LearnCypher.cql contributors: - ["Théo Gauchoux", "https://github.com/TheoGauchoux"] translators: - ["AstiaSun", "https://github.com/AstiaSun"] lang: uk-ua --- Cypher - це мова запитів Neo4j для спрощення роботи з графами. Вона повторює синтакс SQL та перемішує його з таким собі ascii стилем для відображення стуктури графа. Цей навчальний матеріал передбачає, що ви вже знайомі із концепцією графів, зобрема що таке вершини та зв'язки між ними. [Деталі тут](https://neo4j.com/developer/cypher-query-language/) Вершини --- **Відображує запис у графі.** `()` Таким чином у запиті позначається пуста *вершина*. Використовується зазвичай для того, щоб позначити, що вона є, проте це не так вже й важливо для запиту. `(n)` Це вершина яка має назву **n**, можна повторно користуватись нею у запиті. Звернення до вершини **n** починається з нижнього підкреслення та викоритовує camelCase (верблюжий регіст). `(p:Person)` Можна також додати *ярлик* до вершини, в данному випадку - **Person**. Це як тип / клас / категорія. Назва *ярлика* починається з великої літери та викоритовує верблюжу нотацію. `(p:Person:Manager)` Вершина може мати кілька *ярликів*. `(p:Person {name : 'Théo Gauchoux', age : 22})` Вершина також може мати різні *властивості*, в данному випадку - **name** та **age**. Також мають починаєтися з великої літери та використовувати верблюжу нотацію. Наступні типи дозволяється викоритовувати у властивостях: - Чиселиний - Булевий - Рядок - Списки попередніх примітивних типів *Увага! В Cypher не існує типу, що відображає час. Замість нього можна використовувати рядок із визначеним шаблоном або чисельне відображення певної дати.* `p.name` За допомогою крапки можна звернутись до властивості вершини. Зв'язки (або ребра) --- **Сполучають дві вершини** `[:KNOWS]` Це *зв'язок* з *ярликом* **KNOWS**. Це такий же самий *ярлик* як і у вершини. Починається з великої літери та використовує ВЕРХНІЙ\_РЕГІСТР\_ІЗ\_ЗМІЇНОЮ\_НОТАЦІЄЮ. `[k:KNOWS]` Те же самий *зв'язок*, до якого можна звертатись через змінну **k**. Можна подалі використовувати у запиті, хоч це і не обов'язково. `[k:KNOWS {since:2017}]` Те й же *зв'язок*, але вже із *властивостями* (як у *вершини*), в данному випадку властивіть - це **since**. `[k:KNOWS*..4]` Це стуктурна інформація, яку використовують *шляхи*, які розглянуті нижче. В данному випадку, **\*..4** говорить: "Сумістити шаблон із зв'язком **k**, що повторюватиметься від одного до чотирьох разів." Шляхи --- **Спосіб поєднувати вершини та зв'язки.** `(a:Person)-[:KNOWS]-(b:Person)` Шлях описує, що вершини **a** та **b** знають (knows) один одного. `(a:Person)-[:MANAGES]->(b:Person)` Шлях може бути направленим. Цей описує, що **а** є менеджером **b**. `(a:Person)-[:KNOWS]-(b:Person)-[:KNOWS]-(c:Person)` Можна створювати ланцюги зі зв'язків. Цей шлях описує друга друга (**a** знає **b**, який в свою чергу знає **c**). `(a:Person)-[:MANAGES]->(b:Person)-[:MANAGES]->(c:Person)` Ланцюг, аналогічно, також може бути направленим. Шлях описує, що **a** - бос **b** і супер бос для **c**. Шаблони, які часто викоритовуються (з документації Neo4j): ``` // Друг-мого-друга (user)-[:KNOWS]-(friend)-[:KNOWS]-(foaf) // Найкоротший шлях path = shortestPath( (user)-[:KNOWS*..5]-(other) ) // Спільна фільтрація (user)-[:PURCHASED]->(product)<-[:PURCHASED]-()-[:PURCHASED]->(otherProduct) // Навігація по дереву (root)<-[:PARENT*]-(leaf:Category)-[:ITEM]->(data:Product) ``` Запити на створення --- Створити нову вершину: ``` CREATE (a:Person {name:"Théo Gauchoux"}) RETURN a ``` *`RETURN` дозволяє повернути результат після виконання запиту. Можна повертати кілька значень, наприклад, `RETURN a, b`.* Створити новий зв'язок (із двома вершинами): ``` CREATE (a:Person)-[k:KNOWS]-(b:Person) RETURN a,k,b ``` Запити на знаходження --- Знайти всі вершини: ``` MATCH (n) RETURN n ``` Знайти вершини за ярликом: ``` MATCH (a:Person) RETURN a ``` Знайти вершини за ярликом та властивостю: ``` MATCH (a:Person {name:"Théo Gauchoux"}) RETURN a ``` Знайти вершини відовідно до зв'язків (ненаправлених): ``` MATCH (a)-[:KNOWS]-(b) RETURN a,b ``` Знайти вершини відовідно до зв'язків (направлених): ``` MATCH (a)-[:MANAGES]->(b) RETURN a,b ``` Знайти вершини зо допомогою `WHERE`: ``` MATCH (p:Person {name:"Théo Gauchoux"})-[s:LIVES_IN]->(city:City) WHERE s.since = 2015 RETURN p,state ``` Можна використовувати вираз `MATCH WHERE` разом із операцією `CREATE`: ``` MATCH (a), (b) WHERE a.name = "Jacquie" AND b.name = "Michel" CREATE (a)-[:KNOWS]-(b) ``` Запити на оновлення --- Оновити окрему властивість вершини: ``` MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p.age = 23 ``` Оновити всі властивості вершини: ``` MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p = {name: "Michel", age: 23} ``` Додати нову властивіть до вершини: ``` MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p + = {studies: "IT Engineering"} ``` Повісити ярлик на вершину: ``` MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p:Internship ``` Запити на видалення --- Зидалити окрему вершину (пов'язані ребра повинні бути видалені перед цим): ``` MATCH (p:Person)-[relationship]-() WHERE p.name = "Théo Gauchoux" DELETE relationship, p ``` Видалити властивість певної вершини: ``` MATCH (p:Person) WHERE p.name = "Théo Gauchoux" REMOVE p.age ``` *Зверніть увагу, що ключове слово `REMOVE` це не те саме, що й `DELETE`!* Видалити ярлик певної вершини: ``` MATCH (p:Person) WHERE p.name = "Théo Gauchoux" DELETE p:Person ``` Видалити всю базу даних: ``` MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n, r ``` *Так, це `rm -rf /` на мові Cypher !* Інші корисні запити --- `PROFILE` Перед виконанням, показати план виконання запитів. `COUNT(e)` Порахувати елементи (вершини та зв'язки), що відповідають **e**. `LIMIT x` Обмежити результат до x перших результатів. Особливі підказки --- - У мові Cypher існують лише однорядкові коментарі, що позначаються двійним слешем : // Коментар - Можна виконати скрипт Cypher, збережений у файлі **.cql** прямо в Neo4j (прямо як імпорт). Проте, не можна мати мати кілька виразів в цьому файлі (розділених **;**). - Використовуйте команднйи рядок Neo4j для написання запитів Cypher, це легко і швидко. - Cypher планує бути стандартною мовою запитів для всіх графових баз даних (більш відома як **OpenCypher**).