--- language: Cypher filename: LearnCypher-ua.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): ```cypher // Друг-мого-друга (user)-[:KNOWS]-(friend)-[:KNOWS]-(foaf) // Найкоротший шлях path = shortestPath( (user)-[:KNOWS*..5]-(other) ) // Спільна фільтрація (user)-[:PURCHASED]->(product)<-[:PURCHASED]-()-[:PURCHASED]->(otherProduct) // Навігація по дереву (root)<-[:PARENT*]-(leaf:Category)-[:ITEM]->(data:Product) ``` ## Запити на створення Створити нову вершину: ```cypher CREATE (a:Person {name:"Théo Gauchoux"}) RETURN a ``` *`RETURN` дозволяє повернути результат після виконання запиту. Можна повертати кілька значень, наприклад, `RETURN a, b`.* Створити новий зв'язок (із двома вершинами): ```cypher CREATE (a:Person)-[k:KNOWS]-(b:Person) RETURN a,k,b ``` ## Запити на знаходження Знайти всі вершини: ```cypher MATCH (n) RETURN n ``` Знайти вершини за ярликом: ```cypher MATCH (a:Person) RETURN a ``` Знайти вершини за ярликом та властивістю: ```cypher MATCH (a:Person {name:"Théo Gauchoux"}) RETURN a ``` Знайти вершини відповідно до зв'язків (ненаправлених): ```cypher MATCH (a)-[:KNOWS]-(b) RETURN a,b ``` Знайти вершини відповідно до зв'язків (направлених): ```cypher MATCH (a)-[:MANAGES]->(b) RETURN a,b ``` Знайти вершини за допомогою `WHERE`: ```cypher MATCH (p:Person {name:"Théo Gauchoux"})-[s:LIVES_IN]->(city:City) WHERE s.since = 2015 RETURN p,state ``` Можна використовувати вираз `MATCH WHERE` разом із операцією `CREATE`: ```cypher MATCH (a), (b) WHERE a.name = "Jacquie" AND b.name = "Michel" CREATE (a)-[:KNOWS]-(b) ``` ## Запити на оновлення Оновити окрему властивість вершини: ```cypher MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p.age = 23 ``` Оновити всі властивості вершини: ```cypher MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p = {name: "Michel", age: 23} ``` Додати нову властивіcть до вершини: ```cypher MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p + = {studies: "IT Engineering"} ``` Повісити ярлик на вершину: ```cypher MATCH (p:Person) WHERE p.name = "Théo Gauchoux" SET p:Internship ``` ## Запити на видалення Видалити окрему вершину (пов'язані ребра повинні бути видалені перед цим): ```cypher MATCH (p:Person)-[relationship]-() WHERE p.name = "Théo Gauchoux" DELETE relationship, p ``` Видалити властивість певної вершини: ```cypher MATCH (p:Person) WHERE p.name = "Théo Gauchoux" REMOVE p.age ``` *Зверніть увагу, що ключове слово `REMOVE` це не те саме, що й `DELETE`!* Видалити ярлик певної вершини: ```cypher MATCH (p:Person) WHERE p.name = "Théo Gauchoux" DELETE p:Person ``` Видалити всю базу даних: ```cypher 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**).