2011-02-10 17 views
32

È una forma lenta/scadente usare l'operatore $ in in MongoDB con una vasta gamma di possibilità?

posts.find({ 
    author : { 
     $in : ['friend1','friend2','friend3'....'friend40'] 
    } 
}) 

App Engine, per esempio, non vi permetterà di utilizzare più di 30 perché traducono direttamente a una query per ogni elemento dell'array IN, e così invece ti costringono ad utilizzare il loro metodo per la gestione fan out. Sebbene questo sia probabilmente il metodo più efficiente anche in Mongo, il codice per esso è significativamente più complesso, quindi preferirei usare solo questo metodo generico.

Mongo eseguirà queste $ in query in modo efficiente per dataset di dimensioni ragionevoli?

+0

Hai qualche indice sul tuo campo autore? – shingara

+0

Ciao @Derek Dahmer, potresti superare questo problema? Ho avuto a che fare con questo problema. Questo architetto chiamato Edge Collection di MongoDB oggi :) Anch'io voglio usare $ in parametro con enormi matrici. Ma guardo l'impatto sulle prestazioni! http://image.slidesharecdn.com/socialitept2-140724104718-phpapp01/95/socialite-the-open-source-status-feed-part-2-managing-the-social-graph-18-638.jpg?cb= 1406222239 – efkan

risposta

18

Può essere abbastanza efficiente con elenchi di piccole dimensioni (difficile dire ciò che è piccolo, ma almeno in decine/centinaia) per $ in. Non funziona come app-engine poiché mongodb ha indici btree effettivi e non è un column store come bigtable.

Con $ in, salterà nell'indice per trovare i documenti corrispondenti, o percorrerà l'intera raccolta se non c'è un indice da utilizzare.

+0

Per curiosità, qual è la differenza tra gli archivi b-tree e column che fanno sì che GAE debba avere ciascuna una query separata? Non è possibile che anche GAE salti l'indice? –

+2

Bene, gli indici AFAIK in appengine sono implementati in cima all'archivio colonne. Ciò significa che sei limitato alle query di intervallo e non puoi saltare in giro nella memoria il più facilmente possibile con una struttura btree. Cassandra funziona allo stesso modo di GAE utilizzando l'archivio colonne per conservare i dati dell'indice. –

3

Supponendo di aver creato indice sul campo author, dal punto di vista algoritmico, la complessità temporale di $in funzionamento è: $(N*log(M)), dove N è la lunghezza di array e M è la dimensione della collezione.

La complessità momento della $in operazione non cambia a meno che non si cambia un database (Anche se io non credo che nessuno di db può rompere O(N*log(M))).

Tuttavia, dal punto di vista ingegneristico, se N va a un numero grande, è meglio lasciare che il server logica di business per simulare il funzionamento $in, sia batch o uno per uno.

Questo è semplicemente perché: la memoria nei server di database è molto più preziosa della memoria nei server di business logic.