2011-09-26 11 views
7

Il database è vicino a 5 GB. Ho documenti come:Mongo DB: come selezionare elementi con numero di campi nidificati> 0

{ 
    _id: .. 
    user: "a" 
    hobbies: [{ 
     _id: .. 
     name: football 
    }, 
    { 
     _id: .. 
     name: beer 
    } 
    ... 
    ] 
} 

voglio tornare gli utenti che hanno più di 0 "hobby" Ho provato

db.collection.find({"hobbies" : { &gt : 0}}).limit(10) 

e ci vuole tutta la RAM e nessun risultato.

  1. Come eseguire questa selezione?
  2. E come restituire solo: id, nome, conteggio?
  3. Come farlo con il driver ufficiale C#?

TIA

P.S. near ho trovato: "Aggiungi un nuovo campo per le dimensioni delle categorie: è una pratica normale nel mondo dei mongo". è vero?

risposta

8

Hai provato a utilizzare hobbies.length. Non ho ancora testato questo, ma credo che questo sia il modo giusto per interrogare la gamma della matrice in MongoDB

db.collection.find({$where: '(this.hobbies.length > 0)'}) 
+0

questo funziona - ma su piccola quantità di dati. Per il mio compito sembra che dovrei mantenere la variabile "contare". – 1gn1ter

1

Earlier questions spiega come gestire il problema del numero di array. Anche se nel tuo caso se ZERO è davvero l'unico valore che vuoi testare, puoi impostare l'array su null quando è vuoto e impostare l'opzione per non serializzarlo, quindi puoi verificare l'esistenza di quel campo. Ricordarsi di verificare null e di creare l'array quando si desidera aggiungere un hobby a un utente.

Per # 2, a condizione che sia stato aggiunto il campo conteggio è facile selezionare i campi che si desidera tornare dal database e includere il campo conteggio.

2

Questo è un po 'vero.

Secondo il manuale

http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24size

$ dimensione

L'operatore $ dimensione corrisponde a qualsiasi matrice con il numero specificato di elementi . Il seguente esempio potrebbe corrispondere all'oggetto {un: [ "foo"]}, in quanto tale matrice ha un solo elemento:

db.things.find({ a : { $size: 1 } }); 

Non è possibile utilizzare $ dimensioni per trovare una vasta gamma di formati (ad esempio: array con più di 1 elemento). Se è necessario eseguire una query per un intervallo, creare un campo extra size che si incrementa quando si aggiungono elementi

modo da poter controllare per le dimensioni di matrice 0, ma non per cose come 'più grande di 0'

0
  1. se è necessario trovare solo zero hobby, e se la chiave di hobbies non è impostata per qualcuno con zero hobby, utilizzare il flag EXISTS. Aggiungere un indice su "hobby" per il miglioramento delle prestazioni:

    db.collection.find ({hobbies: {$ exists: true}});

  2. Tuttavia, se la persona con hobby zero ha array vuoto, e persona con 1 hobby ha un array con 1 elemento, utilizza questa soluzione generica:

Mantenere una variabile denominata "hcount" (conteggio degli hobby) e impostarlo sempre uguale alla dimensione della serie di hobbies in qualsiasi aggiornamento. indice sul campo "hcount" Poi, si può fare una query come:

db.collection.find({ hcount : 0 }) // people with 0 hobbies  
db.collection.find({ hcount : 5 }) // people with 5 hobbies 

3 - Da @JohnPs rispondono: "$ size" è anche un buon operatore per questo scopo. http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-%24size

16

In questo caso specifico, è possibile utilizzare l'elenco di indicizzazione per risolvere il problema:

db.collection.find({"hobbies.0" : {$exists : true}}).limit(10)

Questo assicura solo che esista un elemento 0th. Puoi fare lo stesso per assicurarti che l'elenco sia più corto di n o tra xey di lunghezza controllando l'esistente di elementi alle estremità dell'intervallo.

7

È possibile (o quasi) verificare la presenza di una serie di array di lunghezze con l'operatore $size utilizzando una logica $not:

db.collection.find({array: {$not: {$size: 0}}}) 
+0

Questa sembra essere la risposta più applicabile a un array che ha una dimensione diversa da zero. – Roddy