Базы данных: Neo4j

Neo4jopen in new window — графовая база данных. В графовых базах данных объекты хранятся в виде узлов и связей между узлами. Объекты могут содержать данные, их можно представить в виде JSON объекта.

Запуск

Запустить Neo4J проще всего через dockeropen in new window.

docker run \
    --name neo4j \
    --publish=7474:7474 --publish=7687:7687 \
    --volume=$HOME/neo4j/data:/data \
    --env=NEO4J_AUTH=none \
    -d \
    neo4j
1
2
3
4
5
6
7

Порт 7374 будет работать как HTTP API, а порт 7687 для Bolt API.

Neo4j Browser

После запуска контейнера docker по адресу http://localhost:7474/ будет доступен браузер.

Язык запросов

Neo4J использует язык Cypheropen in new window для запросов к базе данных. Cypher похож на SQL и предоставляет дополнительные возможности для выборки и изменения графов. Cypher декларативный язык которые описывает, что нужно вернуть, а не как базе данных нужно выбрать данные, это совпадает с SQL. Отличия Cypher в меньших возможностях проверки схемы данных.

Пример запроса на SQL и аналогичного в Cypher:

SELECT movie.name
FROM movie
WHERE movie.rating > 7
1
2
3
MATCH (movie:Movie)
WHERE movie.rating > 7
RETURN movie.title
1
2
3

Следующие примеры с использованием механизма сравнения шаблонов. Cypher позволяет избавится от соединений (join).

SELECT actors.name
FROM actors
 	LEFT JOIN acted_in ON acted_in.actor_id = actors.id
	LEFT JOIN movies ON movies.id = acted_in.movie_id
WHERE movies.title = "The Matrix"
1
2
3
4
5
MATCH (actor:Actor)-[:ACTED_IN]->(movie:Movie {title: 'The Matrix'})
RETURN actor.name
1
2

Пример на Python

Пример использования библиотеки neo4jopen in new window (GitHubopen in new window):

from neo4j import GraphDatabase, RoutingControl

URI = "neo4j://localhost:7687"

def add_friend(driver, name, friend_name):
    driver.execute_query(
        "MERGE (a:Person {name: $name}) "
        "MERGE (friend:Person {name: $friend_name}) "
        "MERGE (a)-[:KNOWS]->(friend)",
        name=name, friend_name=friend_name, database_="neo4j",
    )

def print_friends(driver, name):
    records, _, _ = driver.execute_query(
        "MATCH (a:Person)-[:KNOWS]->(friend) WHERE a.name = $name "
        "RETURN friend.name ORDER BY friend.name",
        name=name, database_="neo4j", routing_=RoutingControl.READ,
    )
    for record in records:
        print(record["friend.name"])

with GraphDatabase.driver(URI) as driver:
    add_friend(driver, "Arthur", "Guinevere")
    add_friend(driver, "Arthur", "Lancelot")
    add_friend(driver, "Arthur", "Merlin")
    print_friends(driver, "Arthur")

# Guinevere
# Lancelot
# Merlin
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

Ссылки

Последниее изменение: 03.01.2025, 20:07:21