72 lines
5.5 KiB
Markdown
72 lines
5.5 KiB
Markdown
# Neo4j golang example
|
||
Команда запуска сервера в Docker для локальной разработки:
|
||
```sh
|
||
docker run -d --name neo4j -p7474:7474 -p7687:7687 -e NEO4J_AUTH=neo4j/password neo4j
|
||
```
|
||
- На порту `7474` будет доступен вебинтерфейс Neo4j: http://localhost:7474
|
||
- Порт `7687` используется для подключения к базе данных через Bolt-протокол.
|
||
- Про Bolt можно детальнее почитать [тут](https://neo4j.com/docs/bolt/current/bolt/)
|
||
|
||
Запросы к neo4j пишутся на языке [Cypher](https://opencypher.org).
|
||
Ниже приведены примеры запросов для создания узлов и связей между ними, а также для поиска связанных узлов.
|
||
## Создание узлов с помощью MERGE
|
||
Запрос:
|
||
```cypher
|
||
MERGE (a:Person {name: $name, age: $age})
|
||
```
|
||
**Объяснение**:
|
||
- `MERGE`: Проверяет, существует ли узел с указанными свойствами. Если не существует, создаёт его. Если существует, повторного создания не будет.
|
||
- `(a:Person ...)`: Создаётся или ищется узел с меткой Person. Метка (label) описывает тип сущности (например, Person для человека).
|
||
- `{name: $name, age: $age}`: Свойства узла. name и age задаются через параметры (обозначены как $name и $age), значения которых передаются из кода.
|
||
|
||
## Создание уникальных связей с помощью MERGE
|
||
Запрос:
|
||
```cypher
|
||
MATCH (a:Person {name: $name1}), (b:Person {name: $name2})
|
||
MERGE (a)-[:FRIENDS]->(b)
|
||
```
|
||
**Объяснение**:
|
||
- `MATCH (a:Person {name: $name1})`: Ищет узел с меткой Person, у которого свойство name равно значению параметра $name1. Этот узел связывается с переменной a.
|
||
- `MATCH (b:Person {name: $name2})`: Аналогично, ищет узел Person с именем $name2 и связывает его с переменной b.
|
||
- `MERGE (a)-[:FRIENDS]->(b`): Проверяет, существует ли связь FRIENDS от узла a к узлу b. Если такая связь существует, ничего не делает. Если не существует, создаёт её.
|
||
- `[:FRIENDS]:` Определяет тип связи. В данном случае это "дружба".
|
||
- `->`: Направление связи. Стрелка указывает, что a дружит с b.
|
||
|
||
## Поиск друзей конкретного человека
|
||
```cypher
|
||
MATCH (a:Person {name: $name})-[:FRIENDS]->(friend)
|
||
RETURN friend.name AS name, friend.age AS age
|
||
```
|
||
**Объяснение**:
|
||
- `MATCH (a:Person {name: $name})`: Ищет узел Person с именем, равным значению $name. Этот узел связывается с переменной a.
|
||
- `-[:FRIENDS]->(friend)`: Находит все узлы, связанные с узлом a связью типа FRIENDS. Эти узлы связываются с переменной friend.
|
||
- `RETURN friend.name AS name, friend.age AS age`: Возвращает свойства найденных узлов:
|
||
- `friend.name` — имя друга.
|
||
- `friend.age` — возраст друга.
|
||
- `AS` используется для задания алиасов, чтобы упростить доступ к возвращённым данным.
|
||
|
||
## Поиск кратчайшего пути между двумя узлами
|
||
Запрос:
|
||
```cypher
|
||
MATCH p = shortestPath((a:Person {name: $start})-[:FRIENDS*]-(b:Person {name: $end}))
|
||
RETURN p
|
||
```
|
||
**Объяснение**:
|
||
- `MATCH p = shortestPath((a:Person {name: $start})-[:FRIENDS*]-(b:Person {name: $end}))`: Находит кратчайший путь `p` между узлами `Person`, где начальный узел имеет имя, заданное параметром `$start`, и конечный узел имеет имя, заданное параметром `$end`. Связь между узлами должна быть типа `FRIENDS`.
|
||
- `RETURN p`: Возвращает найденный путь `p`.
|
||
|
||
## Поиск самого длинного пути между двумя узлами
|
||
Запрос:
|
||
```cypher
|
||
MATCH p = (a:Person {name: $start})-[:FRIENDS*]-(b:Person {name: $end})
|
||
RETURN p, length(p) AS pathLength
|
||
ORDER BY pathLength DESC
|
||
LIMIT 1
|
||
```
|
||
**Объяснение**:
|
||
- `MATCH p = (a:Person {name: $start})-[:FRIENDS*]-(b:Person {name: $end})`: Находит все пути `p` между узлами `Person`, где начальный узел имеет имя, заданное параметром `$start`, и конечный узел имеет имя, заданное параметром `$end`. Связь между узлами должна быть типа `FRIENDS`.
|
||
- `RETURN p, length(p) AS pathLength`: Возвращает каждый найденный путь `p` и его длину в виде `pathLength`.
|
||
- `ORDER BY pathLength DESC`: Сортирует пути по длине в убывающем порядке, чтобы самые длинные пути шли первыми.
|
||
- `LIMIT 1`: Ограничивает результат одним самым длинным найденным путем.
|
||
|