2012-02-29 7 views
6

Ho bisogno di memorizzare alcuni dati che sono essenzialmente solo una serie di coppie chiave-valore di data/indice, in cui le date saranno sempre uniche.MongoDB - È possibile eseguire una query per chiave di array associativo?

mi piacerebbe essere in grado di conservarlo come un array associativo:.

array(
    "2012-02-26" => 5, 
    "2012-02-27" => 2, 
    "2012-02-28" => 17, 
    "2012-02-29" => 4 
) 

ma ho anche bisogno di essere in grado di interrogare le date (vale a dire ottenere tutto ciò in cui la data> 2012-02-27), e così il sospetto che avrò bisogno di utilizzare uno schema più simile:

array(
    array("date"=>"2012-02-26", "value"=>5), 
    array("date"=>"2012-02-27", "value"=>2), 
    array("date"=>"2012-02-28", "value"=>17), 
    array("date"=>"2012-02-29", "value"=>4), 
) 

Ovviamente il primo è molto più pulito e più conciso, ma sarò in grado di interrogare nel modo che sto volendo, e se no ci sono altri schemi che potrebbero essere più adatti?

+0

http://www.php.net/manual/en/mongo.queries.php –

+0

Non memorizzare le date in tale formato. Usa il tempo(); funzione. Renderà più facile ordinare le date e così via. http://php.net/manual/en/function.time.php –

risposta

10

Hai descritto due metodi, permettimi di suddividerli.

Metodo # 1 - Associative Array

Lo strumento fondamentale per l'interrogazione da "array associativo" è l'operatore $exists. Here sono dettagli sull'operatore.

Così si può sicuramente eseguire una query come la seguente:

db.coll.find({ $exists: { 'field.2012-02-27' } }); 

Sulla base della sua descrizione siete alla ricerca di un raggio d'azione, che non corrisponde bene con l'operatore $exists. Anche la versione "array associativo" è difficile da indicizzare.

Metodo # 2 - Array di oggetti

Questo ha sicuramente migliore funzionalità interrogazione:

db.coll.find({ 'field.date': { $gt: '2012-02-27' } }); 

Può anche essere indicizzato

db.coll.ensureIndex({ 'field.date': 1 }); 

Tuttavia, v'è un trade spento all'aggiornamento. Se si desidera incrementare il valore per una data specifica, è necessario utilizzare questo ingombrante operatore posizionale $. Funziona per una serie di oggetti, ma fallisce per qualsiasi cosa con ulteriore nidificazione.

Altre questioni

Un problema con uno di questi metodi è la crescita a lungo termine dei dati. Man mano che si espande la dimensione dell'oggetto, ci vorrà più spazio sul disco e nella memoria. Se si dispone di un oggetto con due anni di dati, è necessario che l'intera serie di 700 elementi sia in memoria per l'aggiornamento dei dati per oggi. Questo potrebbe non essere un problema per i tuoi dati specifici, ma dovrebbe essere considerato.

Allo stesso modo, le query MongoDB restituiscono sempre l'oggetto di livello superiore. Di nuovo, se si dispone di una serie di 700 elementi, li otterrete tutti per ciascun documento corrispondente. Ci sono modi per filtrare i campi che vengono restituiti, ma non funzionano per "matrici di oggetti".

+0

'Se hai un oggetto con due anni di dati, tutta la serie di 700 elementi dovrà essere in memoria per poter aggiornare i dati per oggi' - e se dovessi usare' $ slice' per rimuovere un sottoinsieme dell'array e '$ push' per aggiungere un nuovo elemento a un array? –

+0

In modo che funzioni per restituire i dati, ma solo se si inserisce l'ordine di data. Tuttavia, dal lato server, ha ancora bisogno di trascinare l'intero oggetto in memoria anche se ti passa solo un pezzo di esso. –

+0

Oh, giusto non me ne sono reso conto, ho pensato che fosse abbastanza intelligente da rimuovere solo il sottoinsieme specificato. Questo è un po 'un rompicapo per il mio progetto attuale, grazie per avermi impedito di ottenere 6 mesi di anticipo e di averlo capito! –

Problemi correlati