2012-02-05 13 views
5

Diciamo che ho una collezione in mongodb i cui oggetti hanno una matrice nidificata. Voglio ordinare in base al valore di un particolare elemento dell'array. È possibile?Posso ordinare da un elemento all'interno di un array nidificato in Mongo?

Ad esempio (e ho appena fatto l'esempio), se ho una collezione di tipi di film (azione, commedia, romanticismo) ed esempi presentati dagli utenti, posso trovare tutti gli oggetti in cui un dato utente inviato ordinati dal data del film?

Ad esempio, vorrei trovare tutti i tipi in cui "Aaron" ha inviato un esempio, ordinato per anno di esempio "Aaron" inviato.

È quasi un bisogno in cui clausola nel tipo.

> db.movies.find(). Pretty();

{ 
    "_id" : ObjectId("4f2f07c1ec2cb81a269362c6"), 
    "type" : "action", 
    "examples" : [ 
     { 
      "title" : "Gladiator", 
      "year" : 2000, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Mission Impossiple", 
      "year" : 1996, 
      "submitter" : "Bill" 
     }, 
     { 
      "title" : "The Terminator", 
      "year" : 1984, 
      "submitter" : "Jane" 
     } 
    ] 
} 
{ 
    "_id" : ObjectId("4f2f07edaee5d897ea09f511"), 
    "type" : "comedy", 
    "examples" : [ 
     { 
      "title" : "The Hangover", 
      "year" : 2009, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Dogma", 
      "year" : 1999, 
      "submitter" : "Bill" 
     }, 
     { 
      "tile" : "Airplane", 
      "year" : 1980, 
      "submitter" : "Jane" 
     } 
    ] 
} 

> db.movies.find ({ 'examples.submitter': 'Aaron'}) sorta.. ({ 'Examples.year': 1}) piuttosto();

{ 
    "_id" : ObjectId("4f2f07edaee5d897ea09f511"), 
    "type" : "comedy", 
    "examples" : [ 
     { 
      "title" : "The Hangover", 
      "year" : 2009, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Dogma", 
      "year" : 1999, 
      "submitter" : "Bill" 
     }, 
     { 
      "tile" : "Airplane", 
      "year" : 1980, 
      "submitter" : "Jane" 
     } 
    ] 
} 
{ 
    "_id" : ObjectId("4f2f07c1ec2cb81a269362c6"), 
    "type" : "action", 
    "examples" : [ 
     { 
      "title" : "Gladiator", 
      "year" : 2000, 
      "submitter" : "Aaron" 
     }, 
     { 
      "title" : "Mission Impossiple", 
      "year" : 1996, 
      "submitter" : "Bill" 
     }, 
     { 
      "title" : "The Terminator", 
      "year" : 1984, 
      "submitter" : "Jane" 
     } 
    ] 
} 

Nota i documenti vengono restituiti ordinati per l'anno collezioni (come previsto) - un modo per ordinare solo quelle presentate da un determinato utente? per qualche dettaglio in più sto usando il driver mongo del nodo nativo per nodejs.

risposta

5

... un modo per ordinare solo quelli inviati da un determinato utente?

Non penso che funzionerà come vorreste.

In MongoDB, le query restituiscono interi documenti. Quando si esegue la seguente query, si trovano tutti i documenti in cui qualsiasi submitter corrisponde a 'Aaron'.

> db.movies.find({'examples.submitter': 'Aaron'}) 

Nota che 'Aaron' potrebbe teoricamente corrispondere due volte all'interno dello stesso documento, ma restituire solo quel documento una volta. Questo complica il problema di classificazione.

> db.movies.find({'examples.submitter': 'Aaron'}).sort({'examples.year': 1}) 

Allora, cosa vi aspettate quando un documento contiene due cose da 'Aaron' con diversi anni? Ricorda che possiamo solo ordinare i documenti, non possiamo ordinare l'array interno con la query.

Il problema è che si stanno utilizzando "matrici di oggetti" che complicano l'intero processo. La tua domanda di smistamento presuppone che possiamo agire sugli oggetti interiori e che davvero non possiamo.

Si prega di dare un'occhiata al nuovo Aggregation Framework che può fornire quello che stai cercando. Si noti che questa è attualmente una funzionalità nel ramo instabile.

+0

Non pensavo che sarei stato in grado di farlo ma ho pensato che valeva la pena sparare. Sono contento di averlo presentato in quanto il framework di aggregazione di cui parli mi sembra possa farmi arrivare una volta pronto/stabile. Grazie! – Zugwalt

0

Per il tuo caso, dovrai utilizzare eval e fare ordinamento personalizzato su server side. Dai uno sguardo allo here per un esempio specifico sull'ordinamento. La tua funzione di confronto sarà un po 'più complessa, poiché dovrai passare attraverso gli "esempi" di array e filtrare per submitter.

1

Nel caso in cui nessun altro inciampa su questo, sono stato in grado di risolvere un problema simile con la creazione di un indice come:

{'examples.submitter': 1, 'examples.year': 1} 

Se si forza la query per utilizzare questo indice utilizzando suggerimento ("indexname"), i risultati torneranno in ordine dell'indice.

+0

Potresti approfondire dove hai messo quel file/come funziona? Sono anche alle prese con un problema molto simile a quello qui. – ritmatter

+1

È necessario utilizzare .ensureIndex nella raccolta. Di solito lo fai con un mongo db ide o sulla riga di comando. http://docs.mongodb.org/manual/reference/method/db.collection.ensureIndex/ Per il suggerimento è possibile utilizzare mongodb http://docs.mongodb.org/manual/reference/operator/meta/hint/ o con mangusta utilizzare la funzione di suggerimento sulla query. query.hint ({indiceA: 1, indiceB: -1}) –

Problemi correlati