2012-06-24 12 views
6

Sto memorizzando una stringa in un database insieme ai proprietari della stringa (uno o più proprietari per stringa).Come correlare i dati in MongoDB?

Ho sempre lavorato con MySQL, che è un database relazionale tradizionale. In tal caso, memorizzerei la stringa insieme a un ID univoco in una tabella e quindi all'ID univoco della stringa insieme ai proprietari (come record multipli) in una seconda tabella.

Potrei quindi recuperare le stringhe dai proprietari utilizzando un join di SQL.

Ora sto lavorando su un progetto che utilizza MongoDB, e sto facendo lo stesso come sopra.

questo sarebbe considerato il modo sbagliato quando si lavora con i database NoSQL? Non dovrei pensare in termini di "relazioni" quando lavoro con NoSQL?

Un altro modo che posso pensare di raggiungere lo stesso in MongoDB memorizza in questo modo:

{ 
    "string": "foobar", 
    "owners": [ 
     "owner1", 
     "owner2", 
     "owner3" 
    ] 
} 

Tuttavia, in questo caso, io sono sicuro di come avrei cercare "tutte le stringhe di proprietà di proprietario1" .

+7

Si prega di non utilizzare "NoSQL" come un ombrello. Stai usando MongoDB. Questo è tutto."NoSQL" significa * troppo e troppo poco * :-) –

risposta

2

Questo sembra l'approccio corretto; ricorda, tuttavia, dipende sempre dalla totalità del tuo progetto, quali sono gli obiettivi (prestazioni, flessibilità), quali query desideri eseguire più pesantemente, se devi eseguire query ad-hoc e altri fattori. In generale, tuttavia, l'uso di documenti nidificati, come hai scritto, è l'alternativa corretta all'utilizzo di join e chiavi esterne.

Ricordare anche lo maximum document size (attualmente 16 MB), che costituirebbe un problema se ci sono molti (come centinaia di migliaia) di proprietari di una determinata stringa.

+0

Grazie. Non devo preoccuparmi delle dimensioni massime del documento perché non mi avvicinerò mai. La mia query più comune sarà inserimenti. Molto, molto pochi reperti. – xbonez

5

Per completare la risposta di dbaseman:

Sì, il tuo approccio sembra ok. Si può facilmente cercare "tutte le stringhe di proprietà di proprietario1"

db.collection.find({owners: 'author1'}) 

Questo è possibile perché MongoDB tratta gli array in un modo speciale.

+0

Grazie per aver mostrato un esempio della query. – xbonez

6

Questo sarebbe considerato il modo sbagliato quando si lavora con database NoSQL? Non dovrei pensare in termini di "relazioni" quando lavoro con NoSQL?

Ci sono così tante domande sul caso di embedding e si riduce a così poco.

Qualcosa che non sono stati menzionati qui che devono essere considerati se si desidera incorporare:

  • sarà la dimensione del documento, sia aumentando in maniera massiccia? Se è così allora il documento potrebbe spesso spostarsi su disco, questa è una brutta cosa.
  • disposta la relativa riga hanno una relazione molti join alla collezione sto lavorando su (vale a dire video non può incorporare user). In tal caso, si potrebbero verificare dei problemi durante la copia dei dati ridondanti dalla riga correlata nel documento secondario, soprattutto quando si aggiornano i dati ridondanti.
  • Come sarà necessario visualizzare questi risultati?

La visualizzazione dei risultati è sempre un decisivo per decidere se incorporare o meno. Se è necessario impaginare un numero elevato di righe, ad esempio 1000, sarà necessario utilizzare l'operatore $slice nelle normali query o nel framework di aggregazione. A 1000 ammetto che potrebbe essere abbastanza veloce, ma prima o poi che l'operazione in memoria diventerà più lenta delle normali query (dovrebbe essere sempre così).

Se avete bisogno di una complessa e la visualizzazione dei documenti secondari che si potrebbe desiderare di dividere questi fuori e invece hanno la struttura del documento di:

{ 
    "string": "foobar", 
    "owners": [ 
     ObjectId(), 
     ObjectId(), 
     ObjectId() 
    ] 
} 

Penso che questo possa effettivamente essere una struttura più performante in ogni caso per i dati dal lo owner suona come una riga user in una raccolta users.

Invece di compilare i documenti secondari con dati che potrebbero cambiare l'utente, è sufficiente fare riferimento al numero _id. Questo è abbastanza kool dal momento che è possibile incorporare la relazione, ma allo stesso tempo il documento crescerà molto poco, il che si spera significhi una bassa possibilità di movimento costante del disco, non solo quello, ma un set di lavoro più piccolo che crea un'operazione complessiva più performante. Non solo, ma è ovvio che lo _id di un proprietario cambierà raramente, pertanto le sole operazioni che è necessario eseguire molto probabilmente in questo sottoinsieme di dati sono create ed eliminate.

Torna a ordinamento e impaginazione complessi. Con questi dati è ovviamente possibile ottenere tutti gli ID owner con un singolo round trip e quindi in un altro round è possibile eseguire una query per quelle righe di proprietari all'interno della tabella users con query normali utilizzando uno $in che consente la visualizzazione complessa richiesta.

Quindi questa struttura complessiva, ho trovato, è molto performante.

Ovviamente questa struttura dipende dall'interrogazione, potrebbe essere preferibile invece ospitare l'id della stringa sull'utente, ma in questo caso non è perché un utente può possedere presumibilmente molte stringhe in quanto tale direi che è un molte-> molte relazioni incorporate sul lato delle stringhe.

Speriamo che questo aiuta e non ho fatto il giro in tondo,

3

Quando si tratta di dati incorporati mi consiglia di arrivare a conoscere il comportamento atomicità in Mongo. Un buon punto di partenza sarebbe qui: http://docs.mongodb.org/manual/core/data-modeling/#atomicity

Nel tuo caso specifico quando aggiunta/rimozione di un utente ObjectId (come raccomandato da Sammaye) per la matrice "proprietari", si sta andando a voler utilizzare a findAndModify() operazione su la stringa doc per garantire che quando si verificano molte scritture su quel documento, l'integrità dei dati sia ancora mantenuta.

All'interno di questa operazione, mi consiglia di utilizzare i seguenti operatori:

  1. Quando si aggiungono un proprietario, $ addToSet per evitare duplicati
  2. Quando si rimuove un proprietario, $ tirare

Entrambi sono documentati qui: http://docs.mongodb.org/manual/reference/operators/#update-operators-array

Problemi correlati