---
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):

```
// Друг-мого-друга 
(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}
```

Додати нову властивіcть до вершини:

```
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**).