2011-03-15 15 views
5

Continuando con mi pregunta sobre EAV, estoy considerando usar MongoDB para almacenar los atributos del producto.Doctrine ODM y diseño sin esquema

Voy a almacenar la parte del catálogo de esta aplicación - Categorías, Productos y toda su información relacionada - con MongoDB (u otra base de datos de documentos).

Mi pregunta es, cuando se utiliza un ODM, cada entidad tiene un esquema, que esencialmente no tiene en cuenta la ventaja del esquema de usar una base de datos NoSQL, ¿no es así?

Si esto es correcto, ¿por qué alguien usaría un ODM?

EDIT: encontré un related question, ¿podría obtener la funcionalidad de atributos del producto utilizando un Hash?

Respuesta

5

La solución es utilizar un @Hash

Aquí está un ejemplo muy básico que hice arriba:

<?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; 
    } 

} 

Añadir algunos datos:

<?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(); 

Entonces consulta, encontrar un producto con el color "Negro" y un tamaño de pantalla mayor que 20:

<?php 

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

Todavía no estoy seguro de si esta es la mejor manera de hacerlo y mi investigación aún está en curso.

1

Aunque nada hace cumplir esto, es una buena práctica tener un esquema básico para una colección. Casi todos los ODM le permiten agregar campos no especificados en la clase. Suponiendo que la aplicación lo permita, también puede dejar fuera los valores de campo.

La ventaja real de un datastore sin esquema, sin embargo, no es tanto que sus campos de nivel superior puedan variar de un documento a otro, sino que esos campos pueden ser estructuras de datos complejas. Cada producto puede tener un campo de atributos que es una matriz, pero el contenido de esa matriz puede ser arbitrariamente largo o corto, y puede contener hashes con varias estructuras. Su ODM debería agregar una capa de Objeto encima de estos valores hash si así lo solicita.

La última ventaja es la actualización del esquema. En SQL agregar o eliminar un campo es una operación monolítica que también consume mucho tiempo. Con un poco de planificación, puede agregar o eliminar campos de documentos a medida que se accede a ellos. Simplemente necesita un código para manejar el esquema desactualizado.

Cuestiones relacionadas