Доктрина ODM и дизайн без схемы

Продолжая свой вопрос о EAV, я рассматриваю возможность использования MongoDB для хранения атрибутов продукта. .

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

Мой вопрос: при использовании ODM каждая сущность имеет схему, которая по существу игнорирует преимущество использования базы данных NoSQL без схемы, не так ли?

Если это правильно, зачем кому-то использовать ODM?

РЕДАКТИРОВАТЬ: я нашел связанный вопрос, Могу ли я добиться функциональности атрибутов продукта с помощью хеша?


person Cobby    schedule 15.03.2011    source источник


Ответы (2)


Решение - использовать @Hash

Вот ОЧЕНЬ простой пример, который я сделал:

<?php

/**
 * @Document
 */
class Product
{

    /**
     * @Id
     */
    private $id;

    /**
     * @String
     */
    private $name;

    /**
     * @Hash
     */
    private $attributes = array();

    public function getId()
    {
        return $this->id;
    }

    public function setName($name)
    {
        $this->name = $name;
    }

    public function getName()
    {
        return $this->name;
    }

    public function addAttribute($name, $value)
    {
        $key = preg_replace('/[^a-z0-9\ \_]/i', '', $name);
        $key = preg_replace('/\s+/i', '_', $key);
        $key = strtolower($key);
        $this->attributes[$key] = array('value' =>$value, 'label' => $name);
    }

    public function getAttribute($name)
    {
        return $this->attributes[$name];
    }

    public function getAttributes()
    {
        return $this->attributes;
    }

}

Добавьте данные:

<?php

$pen = new Product();
$pen->setName('Cool Pen');
$pen->addAttribute('Weight', 12);
$pen->addAttribute('Ink Colour', 'Red');
$pen->addAttribute('Colour', 'Black');

$tv = new Product();
$tv->setName('LED LCD TV');
$tv->addAttribute('Weight', 12550);
$tv->addAttribute('Screen Size', 32);
$tv->addAttribute('Colour', 'Black');

$dm->persist($pen);
$dm->persist($tv);

$dm->flush();

Затем выполните запрос и найдите продукт с цветом "Черный" и размером экрана больше 20:

<?php

$query = $dm->createQueryBuilder('Catalogue\Product');
$products = $query->field('attributes.colour.value')->equals('Black')
                ->field('attributes.screen_size.value')->gte(20)
                ->getQuery()->execute();

Я все еще не уверен, что это лучший способ сделать это, и мои исследования все еще продолжаются.

person Cobby    schedule 15.03.2011

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

Однако реальное преимущество бессхемного хранилища данных не столько в том, что поля верхнего уровня могут варьироваться от документа к документу, сколько в том, что эти поля могут быть сложными структурами данных. Каждый продукт может иметь поле атрибутов и, которое является массивом, но содержимое этого массива может быть сколь угодно длинным или коротким и может содержать хэши с различными структурами. Ваш ODM должен добавить объектный слой поверх этих хэшей, если вы попросите об этом.

Последнее преимущество - обновление схемы. В SQL добавление или удаление поля - это монолитная операция, которая также занимает много времени. Немного спланировав, вы можете добавлять или удалять поля из документов по мере доступа к ним. Вам просто нужен код для работы с устаревшей схемой.

person John F. Miller    schedule 21.03.2011