2011-03-15 14 views
5

Proseguendo dalla mia domanda circa EAV, Sto pensando di utilizzare MongoDB per memorizzare attributi di prodotto.Dottrina ODM e lo schema-less Design

ho memorizzerà la parte catalogo di questa applicazione - Categorie, prodotti e tutte le loro informazioni correlate - con MongoDB (o un altro database di documenti).

La mia domanda è, quando si utilizza uno ODM, ogni entità ha uno schema, che essenzialmente trascura il vantaggio dello schema di utilizzare un database NoSQL, non è vero?

Se questo è corretto, perché qualcuno dovrebbe usare un ODM?

EDIT: ho trovato un related question, potrei realizzare il prodotto attributi funzionalità utilizzando un hash?

risposta

5

La soluzione è quella di utilizzare un @Hash

Ecco un esempio molto semplice che ho fatto fino:

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

} 

aggiungere alcuni dati:

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

Poi interrogazione, trovare un prodotto con il colore "nero" e una dimensione dello schermo maggiore di 20:

<?php 

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

Non sono ancora sicuro se questo è il modo migliore per farlo e la mia ricerca è ancora in corso.

1

Anche se nulla impone questo, è una buona pratica di avere uno schema di base per una collezione. Quasi tutti gli ODM ti consentono di aggiungere campi non specificati nella classe. Supponendo che l'applicazione lo consenta, puoi anche escludere i valori dei campi.

Il vero vantaggio di un datastore di schemi, tuttavia, non è tanto il fatto che i campi di livello superiore potrebbero variare dal documento al documento, ma che quei campi possono essere strutture di dati complesse. Ogni prodotto può avere e attribuisce un campo che è un array, ma il contenuto di tale array può essere arbitrariamente lungo o breve e può contenere hash con varie strutture. Il tuo ODM dovrebbe aggiungere un livello Oggetto sopra questi hash se lo chiedi.

L'ultimo vantaggio è nell'aggiornamento dello schema. In SQL l'aggiunta o la rimozione di un campo è un'operazione monolitica che richiede anche molto tempo. Con un po 'di pianificazione, è possibile aggiungere o rimuovere campi dai documenti al momento dell'accesso. Hai semplicemente bisogno di codice per gestire lo schema non aggiornato.