Статьи

Эпоха объектно-документного картирования

Картопостроитель данных модели является механизмом персистенции , где модель приложения и источник данных , не имеют никаких зависимостей между друг с другом. Например, группа классов PHP и реляционная база данных могут использоваться вместе без того, чтобы классы PHP расширяли базовый класс Active Record, благодаря Data Mapper, подобному Doctrine 2.

Но каждый раз, когда мы говорим о шаблоне Data Mapper, мы предполагаем, что на другой стороне границы постоянства существует реляционная база данных . Мы всегда сохраняем объекты; мы всегда сопоставляем их с таблицами MySQL или Postgres; но это не обязательно .

На самом деле, вы можете хранить объекты также в хранилищах NoSQL, не превышая импеданс, который уже существует в реляционных базах данных. Doctrine расширяется за счет двух проектов , целью которых является тиражирование простого объектно-реляционного отображения Doctrine 2 в другие магазины.

Этими двумя проектами являются сопоставители объектов-документов MongoDB и CouchDB . Поскольку в обоих случаях основной единицей постоянства является документ, объекты (или их группа) хранятся в виде документов. Процесс поиска зависит от особенностей базовой базы данных: он может состоять из простых запросов (MongoDB) или просто из уникального идентификатора (CouchDB).

Как работает ODM?

Если вы используете Doctrine 2, вы обнаружите, что многие из его концепций хорошо подходят для других картографов. Вместо сущностей у нас есть документы в нашей модели:

<?php

namespace Documents;

use Doctrine\Common\Collections\ArrayCollection;

/**
 * @Document(indexed=true)
 */
class Article
{

Вместо столбцов у нас есть поля:

    /** @Id(type="string") */
    protected $id;
    /** @Field(type="string") */
    protected $title;
    /** @Field(type="string", indexed=true) */
    protected $slug;

И вместо EntityManager у нас есть DocumentManager как Фасад Отображателя данных (несмотря на изменение имени, его методы почти одинаковы):

$user = new User();
$user->id = "myuser-1234";
$user->username = "test";

$this->dm->persist($user);
$this->dm->flush();
$this->dm->clear();

$userNew = $this->dm->find($this->type, $user->id);

Существует много вариантов повторного использования между различными проектами: Doctrine \ Common является зависимостью для всех них, и вы сможете использовать один и тот же ArrayCollection с любым из отображений.

Характеристики

Там действительно все, что мне нужно, чтобы начать:

  • хранение новых документов, обновление, удаление ; в значительной степени то, что вы ожидаете;
  • Шаблон единицы работы для отслеживания того, что было изменено, и выполнения единственного сброса () для сохранения изменений;
  • поддержка коллекций и ассоциаций «один ко многим» или «многие к одному» ;
  • support for embedded documents (read Value Objects); both embedding of one or many objects as document fields is possible. This is a striking difference with respect to ORMs: Doctrine 2 does not support Value Objects mapping.
  • cascade of persistence and removal of objects;
  • specification of the mapping metadata via annotations, XML, YAML or PHP (like for Doctrine 2).

Projects status

The concept of Object-Document Mapper, at least in this name, is pretty unique to PHP and Ruby. Mandango is a PHP alternative and Mongoid a Ruby one, for the MongoDB case.

Both projects are in the midst of releasing their first stable version: we are talking about bleeding edge technology here.

The MongoDB mapper has been around for more than an year and is now in beta3. The CouchDB has an alpha release, but I found out that the current version shipped via PEAR is broken: if you want to play with it, checkout it from github and initialize its submodules (the standalone Symfony components and Doctrine\Common):

git clone https://github.com/doctrine/couchdb-odm.git couchdb_odm
cd couchdb_odm
git submodule init
git submodule update

For the MongoDB mapper, the PEAR installation should suffice:

pear install pear.doctrine-project.org/DoctrineMongoDBODM-1.0.0BETA3

Conclusions

I think I’m going to explore more the CouchDB ODM, since it is a departure from the relational model. MongoDB is still similar to traditional databases in the way queries are satisfied: specifying a set of constraints like in SQL WHERE clauses. I’m more interested instead in approached that skip the Mapper for reporting (like Command-Query Responsibility Separation), and maybe CouchDB could be a good fit.

By the way, object-document mapping is an alternative to explore: Data Mappers are all the rage today in PHP (they already were yesterday in other languages.) If we already accept that relational databases aren’t always the solution, extending NoSQL with Data Mappers is a natural choice.