NEO4J - Графовые базы данных
Всем привет! Предлагаю рассмотреть интересную тему - графовая система управления базами данных в Neo4j:
- Установим и настроим Neo4j;
- Создадим базы данных с использованием Python;
- Познакомимся с базовым синтаксисом языка Cypher для создания запросов;
- Рассмотрим пример использования данной СУБД.
Что такое Neo4j или немного теории:
Neo4j — это графовая система управления базами данных с открытым исходным кодом, реализованная на Java. Она является ведущей графовой СУБД в мире. Аналогами Neo4j являются Oracle NoSQL Database, HypherGraphDB, GraphBase, InfiniteGraph и AllegroGraph.
Всем известно, что такое граф, и из чего он состоит. Так вот, графовые базы данных представляет собой набор объектов, где объекты связаны между собой, подобно как в графе вершины (узлы), связанные через ребра (отношения).
Почему графы и где они используются?
Графы – это удобная и наиболее понятная визуальная система описания данных. Обычно они используются в геоинформационных системах, логистике, социальных сетях и т.п.
На этом теории достаточно, переходим к практике:
Итак, для того чтобы работать с любой базой данных, необходимы данные, как бы тавтологично это не звучало. Для примера, будем использовать уже готовые таблицы (формат CSV) с данными, которые содержать информацию о работе интернет-магазина. Все необходимые данные находятся тут.
Ход работы:
- Скачиваем среду разработки Neo4j Desktop с официального сайта. Больше информации можно прочесть в гайде для разработчиков
- Создаем базу данных
Кликаем на «New» чтобы создать новый проект. После нажимаем на Add -> local DBMS и уже в самом конце называем её (больше информации тут). После всех проделанных действий необходимо запустить её и открыть Neo4j Browser (большая синяя кнопка с надписью «Open»).
3. Добавление администратора.
В Neo4j browser необходимо ввести команду server user add, для того, чтобы добавить пользователя и после заполнить все поля. В поле roles нужно выбрать admin.
4. Python + Neo4j. Подключение к СУБД.
Для того чтобы подключится к базе данных, необходимо установить библиотеку neo4j.
После импортируем GraphDatabase для подключения к СУБД.
Далее представлен код для подключения
Запросы в Neo4j пишутся на языке Cypher. Он интуитивно понятный для освоения. Документацию по этому языку можно прочитать перейдя по ссылке.
Итак, подключаемся к СУБД. Создаем объект connection и передаем имя пользователя и пароль (который создавали при регистрации пользователя). Далее передаем запрос на создание самой базы данных «graphDb» — это название БД.
Далее необходимо загрузить все данные из таблицы в БД (загружаем таблицу Product). Для этого пишем запрос:
Как работает данный запрос? Он загружает CSV-файл из github, после построчно считывает данные, разделяя их по запятой (FIELDTERMINATOR ‘,’). Далее связываем узлы (объекты) и создаем свойства объекта
Поздравляю! Вывели узлы Product. Если нажать на один узел, то в окне справа появятся все свойства (productName, productID, UnitPrice), которые мы прописывали в запросе.
Далее создаем запросы на загрузку остальных данных из других таблиц. Код можно посмотреть в GitHub. В итоге в левом окне должно быть 5 узлов:
Можно вывести все узлы в одно окно. Для этого необходимо прописать следующий запрос:
Пока наши узлы (объекты) не имеют отношений с другими узлами.
5. Запросы на создание отношений.
Допустим, нам нужно посмотреть какие заказы выполнили сотрудники. Для этого нужно связать узлы (объекты) Order и Employee. Создаем следующий запрос:
MATCH – это основной способ получения данных в текущем наборе привязок. С помощью CREATE создаем саму связь, синтаксис напоминает строение графа, в «[]» прописываем название связи. Более наглядно это можно продемонстрировать следующим образом:
Результат:
Данный запрос создаст связь, которая отобразиться в левом окне. Эта связь показывает отношение между сотрудником и заказами, который выполнил сотрудник. Например, Aleekseev -> SOLD-> Grandma’s Bakery, означает, что сотрудник Алексеев продал что-то Grandma’s Bakery (это что-то мы узнаем чуть позже).
Чтобы узнать какие данные хранятся в узле, достаточно просто на него нажать и в правом окне появится информация об объекте. Важно отметить, что здесь появляется информация, а именно свойства, которые прописывали в запросе.
Теперь нам необходимо узнать, какой именно продукт приобрели в заказе. Для этого пишем следующий запрос:
Результат:
И так, у нас есть связи сотрудника с заказом и с проданным в заказе продуктом. Теперь создадим связь между продуктом и поставщиком, а также свяжем его с категорией товара. Для этого выполните два запроса:
Все узлы имеют отношения. Теперь можно увидеть, как каждый объект связан друг с другом. Для этого выведите все узлы.
Давайте проанализируем сотрудника Timofeeva. Из графа видно, какие именно товары она продала «Fresh product», и кто был поставщиком данных товаров.
Также помним, что это все-таки база данных, и здесь можно узнать имя, фамилию и должность сотрудника — кликнув по объекту.
6. Запросы для поиска конкретной информации.
До этого все запросы писались через Python, но их можно создавать в самой Neo4j browser (в строке сверху).
Допустим, нужно найти конкретного поставщика (например, Peter ‘s Lands), и какие продукты он поставляет. Пишем запрос:
Необязательно всегда выводить нужную информацию в графах, можно и в таблице. Например, выведем информацию о том какие продукты продал сотрудник Nekrasov.
Результатом этого запроса будет:
Разница в том, какие данные возвращаем. Если это свойства объекта, то результатом выполнения запроса будет таблица.
Также мы можем выгрузить данные из БД. Для этого импортируем pandas.
Результат:
Вы можете создавать любые запросы, и для этого в документации есть очень хорошая карта со всем синтаксисом Cypher Refcard.
После того, как рассмотрели базовые вопросы, касаемые Neo4j, нужно разобраться с вопросом, где же все-таки применяются графовые базы данных в реальных проектах? Один из таких примеров — это рекомендации по предложению продукта (товара). Мы же рассмотрим пример «Рекомендация статей для читателей» с использование Neo4j.
Пример «Рекомендация статей для читателей»
Суть нашей системы рекомендаций статей следующая: необходимо предлагать нашим читателям альтернативную статью. Например, если читатель проявляет интерес к определенной категории статей, можно создать рекомендацию, содержащую альтернативные статьи.Чтобы показать, как это работает, давайте создадим модель данных:
- Создаем модель данных:
Наша система рекомендаций будет содержать следующие объекты с атрибутами:
- articles – title,
- category_articles – title,
- reader – name, email, nickname,
- RecommendationArticleToReader – nickname
Отношения будут следующие:
На этом у нас закончилось моделирование сущностей.Также стоит обратить внимание, что в Neo4j нет необходимости моделировать двунаправленные отношения, например, статья находится в категории, а категория имеет множество статей. Графические базы данных позволяют отслеживать ребра в обоих направлениях.
Кстати одним из преимуществ графических баз данных от реляционных в том, что мы можем добавлять, изменять и удалять сущности (узлы) и связи (ребра), не беспокоясь о внешних ключах.
2. Работа в Neo4J:
Заполняем нашу БД в соответствии с моделью, которую мы определили выше. Запросы будем писать в Neo4j Browser.
Загружаем данные в формате csv c github:
Далее создаем отношения article-[:IS_IN]-> category и reader-[:READ]->article:
Итог:
3. Создадим рекомендации статей для читателей основываясь на прочитанных статьях. Для этого пишем запрос:
В запросе отбираем прочитанные статьи от непрочитанных, создавая новую сущность RecommendationArticleToReader, которая содержит nickname читателей. После создаем новую связь: RECOMMEND_READING, где связываем не прочитанную статью, той же категории, что и статьи, которые уже прочитал читатель. В итоге получим следующий граф:
Обращаю внимание, что в связи: RECOMMEND_READING передается email читателя.
Итак, теперь выведем все связи и сущности, а также проанализируем получившийся граф, а именно, возьмем одного читателя и посмотрим все связи. Для примера возьмем Ivan Ivanov. Из графа видно, что он прочёл, и какие статьи ему предлагается прочитать.
Давайте напишем запрос чтобы вывести только рекомендации по читателю Ivan Ivanov:
Получаем:
4. Также можно попробовать рекомендовать статьи, основываясь на прочтенных статьях других читателей, которые имеют хотя бы одну прочтённую статью с другим читателем. Для этого пишем запрос, который выведет всех читателей и прочтенные статьи:
Из графа видно, что у многих читателей есть общие прочитанные статьи, и мы можем рекомендовать им те статьи, которые прочёл читатель (с которым есть общая прочтённая статья), но не прочел другой. Для примера возьмем читателя Ivan Ivanov. Пишем запрос:
С помощью этого запроса мы возвращаем статью, не прочитанную Ivan’ом, но прочитанную читателем, с которым у Ivan’a есть общая прочитанная статья. Т.е. в переменной article_2 хранится статья, не прочитанная Ivan’ом. Для примера возвратили все переменные чтобы увидеть связь между сущностями.
Но, чтобы вывести только нужные статьи, достаточно вернуть только переменную article_2.
Итак, рассмотрен базовый функционал Neo4j и примеры его использования. Это очень удобный и понятный инструмент графовых баз данных. Но использовать его стоит только для решения задач, которые решаются с использованием графов. Важно также отметить, что Neo4j - это не фреймворк и сравнивать его с gephi или networkx нет смысла. Потому что Neo4j не просто визуализирует данные, но и содержит их, так как является базой данных.