Статьи

Представляем Neo4j Symfony Bundle

Эта статья была рецензирована Верном Анчетой и Кристофом Виллемсеном . Спасибо всем рецензентам SitePoint за то, что сделали контент SitePoint как можно лучше!


Почему графики?

Нет такой вещи, как отключенная информация, независимо от того, куда вы смотрите — люди, события, места, вещи, документы, приложения и информация о них все тесно связаны. По мере роста объема данных растет количество и динамичность их соединений. И если в прошлом вы пытались хранить и запрашивать эти тесно связанные, полуструктурированные данные в любой базе данных, вы, вероятно, столкнулись с множеством проблем.

Пример графика

Помеченный граф свойств в собственной базе данных графов

Neo4j был создан для обработки именно этой реальной информации без ущерба для количества и типов соединений, которые вы можете иметь, связанных с вашими сущностями. Это база данных NoSQL с открытым исходным кодом, которая использует График помеченных свойств для хранения сущностей вашей доменной модели (диаграммы) как узлов, а их соединений — как отношений, каждая из которых может иметь произвольные свойства.

Узлы и релизы со свойствами

Neo4j — это не просто графический слой поверх другой базы данных, а полноценная транзакционная (ACID) база данных со всем, начиная от управления страницами записей на диске и заканчивая масштабируемым и безопасным кластером. А в качестве собственной базы данных графов она использует выделенные структуры данных для эффективного хранения и запроса данных с высокой степенью связи. В отличие от других баз данных, (сложные) запросы JOIN не вычисляются повторно во время запроса. Вместо этого отношения между сущностями хранятся напрямую. Во время запросов ядро ​​базы данных может использовать прямые указатели записи для поиска в постоянном времени.

Открытый язык запросов Cypher

Это не просто распространяется на моделирование или хранение, даже язык запросов графов Cypher, который поставляется с Neo4j, ориентирован на графические шаблоны, на этот раз представленные в вашем запросе как ASCII-art: (dan:Person {name:"Dan"})-[:LOVES]->(ann:Person {name:"Ann"})

 MATCH (c:Customer)-[:BOUGHT]->(:Product)<-[:BOUGHT]-(o:Customer)-[:BOUGHT]->(reco:Product)
WHERE c.id = 123 AND NOT (c)-[:BOUGHT]->(reco)
RETURN reco.name, count(*) as frequency
ORDER BY frequency DESC LIMIT 10;

Symfony, фреймворк быстрой разработки для PHP

Symfony — образец для подражания фреймворков для современного PHP. Структура имеет компонентный подход и существует уже 11 лет. Из экосистемы Symfony мы видели такие проекты, как Composer, Twig, Swiftmailer, Assetic, Monolog и многие другие. Благодаря компонентному подходу другим проектам и фреймворкам стало легко использовать код из Symfony. Такие проекты, как Laravel, Silex, Sylius, Drupal, phpBB, eZ, используют компоненты Symfony.

Ключевым фактором успеха Symfony является гибкость фреймворка в сочетании с простотой использования. Стандартная версия Symfony поставляется с Doctrine в качестве абстракции уровня базы данных по умолчанию, которая поддерживает некоторые основные базы данных, такие как MySQL и MongoDB. Но ни уровень базы данных, ни Doctrine не являются основными гражданами Symfony. Их можно легко заменить чем-то другим.

Представляем Symfony Neo4j Bundle

Чтобы обеспечить плавную интеграцию между Neo4j и Symfony, мы создали SymfonyNeo4jBundle. Он оборачивает отличный клиент сообщества PHP от Graphaware и создает солидный опыт Symfony. Благодаря интеграции с WebProfiler вы увидите все вызовы вашей базы данных, все запросы и их результаты. Вы даже сможете увидеть любые исключения, возникающие при взаимодействии с базой данных. Вы также получите подробную статистику о каждом вызове базы данных. Это облегчает отладку вашего приложения.

Пакет также интегрирует клиентские события с диспетчером событий Symfony. Теперь вы можете создавать подписчиков на события, которые слушают взаимодействия с Neo4j, например, для интеграции с MonologBundle для регистрации всех ваших запросов к базе данных.

В комплект не входит то, как вы используете Neo4j. Использование OGM необязательно. Опытные пользователи Neo4j будут иметь полный контроль над клиентом и тем, что исполняет Сайфер.

API как Doctrine

Для разработчиков, которые знакомы с Doctrine, они будут знать, как использовать OGM GraphAware (Object Graph Mapper). OGM имеет EntityManager, который реализует интерфейс ObjectManager Doctrine, который дает вам такие функции, как «найти», «удалить», «сохранить» и «сбросить». Разработчики будут иметь точно такой же опыт работы с моделями из Neo4j OGM по сравнению с Myct EntityManager в Doctrine.

конфигурация

Как и в большинстве современных сред, Symfony отделяет конфигурацию от кода. Это хорошая практика программного обеспечения, которой придерживается Neo4jBundle. Он предоставляет возможность легко настроить несколько соединений, несколько клиентов и несколько менеджеров сущностей. Для каждого соединения вы можете решить, хотите ли вы использовать HTTP или новый двоичный протокол «болт».

Благодаря компоненту конфигурации Symfony вы можете использовать Yaml, XML или PHP для указания своей конфигурации. Конфигурация по умолчанию настроит одно соединение на 127.0.0.1:7474

Начало работы с Symfony-Neo4j-Bundle

После установки пакета вы можете начать пользоваться клиентами

 $client = $this->get('neo4j.client');
$results = $client->run('MATCH (n:Movie) RETURN n LIMIT 5');
foreach ($results->records() as $record) {
   $node = $record->get('n');
   echo $node->get('title'); // "The Matrix"
}

Если вы привыкли к Doctrine, вы можете использовать OGM. Вам необходимо добавить аннотации к своим моделям, чтобы OGM правильно понимал и отображал свойства.

 use GraphAware\Neo4j\OGM\Annotations as OGM;

/**
 * @OGM\Node(label="User")
 */
class User
{
    /** @OGM\GraphId() */
    protected $id;

    /** @OGM\Property(type="string") */
    protected $name;

    /** @OGM\Property(type="int") */
    protected $age;

    // Getters and setters
}
 $em = $this->get('neo4j.entity_manager');

$bart = new User('Bart Johnson', 33);
$em->persist($bart);
$em->flush();

// Retrieve from database
$john = $em->getRepository(User::class)->findOneBy('name', 'John Doe');
echo $john->getAge();

Вот пример того, как может выглядеть профилировщик:

Пример страницы профилировщика Symfony

Отношения и отношения сущностей

Основное отличие от Doctrine и MySQL заключается в том, что в Neo4j отношения первоклассные. Они так же важны, как и сами узлы. Чтобы создать простые отношения между человеком и фильмом, вы должны использовать аннотацию @OGM\Relationship

 use GraphAware\Neo4j\OGM\Annotations as OGM;
use GraphAware\Neo4j\OGM\Common\Collection;

/**
*
* @OGM\Node(label="Person")
*/
class Person
{
   /**
    * @var int
    *
    * @OGM\GraphId()
    */
   protected $id;

   // other code

   /**
    * @var Movie[]|Collection
    *
    * @OGM\Relationship(type="ACTED_IN", direction="OUTGOING", collection=true, mappedBy="actors", targetEntity="Movie")
    */
   protected $movies;

   public function __construct()
   {
       $this->movies = new Collection();
   }

   // other code

   /**
    * @return Movie[]|Collection
    */
   public function getMovies()
   {
       return $this->movies;
   }
}

Класс Movie имеет отношение INCOMING от Person.

 use GraphAware\Neo4j\OGM\Annotations as OGM;
use GraphAware\Neo4j\OGM\Common\Collection;

/**
*
* @OGM\Node(label="Movie")
*/
class Movie
{
   /**
    * @var int
    *
    * @OGM\GraphId()
    */
   protected $id;

   // other code

   /**
    * @var Person[]|Collection
    *
    * @OGM\Relationship(type="ACTED_IN", direction="INCOMING", collection=true, mappedBy="movies", targetEntity="Person")
    */
   protected $actors;

   public function __construct()
   {
       $this->actors = new Collection();
   }

   // other code

   /**
    * @return Person[]|Collection
    */
   public function getActors()
   {
       return $this->actors;
   }
}

Сама связь может иметь также свойства. Пример, если пользователь оценивает фильм, тогда отношения, вероятно, будут иметь оценку. Это может быть достигнуто с помощью сущностей отношений. Узнайте больше о них в документации OGM .

Пример проекта

Есть пример проекта, который вы можете использовать для тестирования пакета. Используйте следующие шаги для установки проекта:

 git clone git@github.com:neo4j-examples/movies-symfony-php-bolt.git
composer install

Исправление импорта данных (https://neo4j.com/developer/example-project/#_data_setup)

 php bin/console server:run

Перейти к http://127.0.0.1:8000/

Больше информации о пакете в репозитории на Github. Пожалуйста, дайте нам комментарии и отзывы о том, что мы сделали правильно и как мы можем улучшить. Не стесняйтесь поднимать вопросы или способствовать проекту.

Ресурсы: