Базы данных: 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
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
2
3
MATCH (movie:Movie)
WHERE movie.rating > 7
RETURN movie.title
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"
2
3
4
5
MATCH (actor:Actor)-[:ACTED_IN]->(movie:Movie {title: 'The Matrix'})
RETURN actor.name
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
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