2012-09-14 17 views
12

Sto cercando un modo per ordinare una matrice nidificata di oggetti. Ecco un esempio:MongoDB: ordina la matrice nidificata di oggetti

answers: [ 
      {name: 'paul', state: 'RU'}, 
      {name: 'steve', state: 'US'}, 
      {name: 'mike', state: 'DE'}, 
      ... 
     ] 

Supponiamo ora voglio trovare tutte le name, della matrice answers, ma l'ordinamento in ordine ascendente, come posso realizzare questo?

risposta

23

Lo memorizzerei nell'ordine in cui lo desideri. Oppure ordinalo dopo averlo estratto, dal lato del cliente.

Se nessuno di questi sono possibili, è possibile utilizzare il aggregation framework:

> db.test.insert({answers: [ 
...     {name: 'paul', state: 'RU'}, 
...     {name: 'steve', state: 'US'}, 
...     {name: 'mike', state: 'DE'}]}); 
> db.test.insert({answers: [ 
...     {name: 'paul', state: 'RU'}, 
...     {name: 'steve', state: 'US'}, 
...     {name: 'xavier', state: 'TX'}]}); 

db.test.aggregate([ 
    {$unwind: "$answers"}, 
    {$sort: {"answers.name":1}}, 
    {$group: {_id:"$_id", answers: {$push:"$answers"}}} 
]); 

produce:

{ 
    "result" : [ 
    { 
    "_id" : ObjectId("5053b2477d820880c3469364"), 
    "answers" : [ 
     { 
     "name" : "paul", 
     "state" : "RU" 
     }, 
     { 
     "name" : "steve", 
     "state" : "US" 
     }, 
     { 
     "name" : "xavier", 
     "state" : "TX" 
     } 
    ] 
    }, 
    { 
    "_id" : ObjectId("5053af9f7d820880c3469363"), 
    "answers" : [ 
     { 
     "name" : "mike", 
     "state" : "DE" 
     }, 
     { 
     "name" : "paul", 
     "state" : "RU" 
     }, 
     { 
     "name" : "steve", 
     "state" : "US" 
     } 
    ] 
    } 
], 
    "ok" : 1 
} 
-2

Dopo aver eseguito un find() è possibile utilizzare sort() sul valore di ritorno.

db.collection.find({},{"answers.name":1}).sort({"answers.name":1}) 

Il ritrovamento estrarrebbe i campi nome di tutti i documenti nella raccolta. L'ordinamento quindi li ordinerebbe per nome, in ordine crescente.

http://www.mongodb.org/display/DOCS/Sorting+and+Natural+Order

+1

Hai bisogno di virgolette intorno ai tuoi tasti "" answer.name "'. Ma non credo che il tuo codice faccia quello che sta cercando ... –

+4

Il tuo esempio elencherà tutti i documenti con i loro campi '_id' e' name', ordinati per nome in ogni array. 'Sort()' funziona a livello di documento e non riordina le matrici all'interno dei documenti. – Stennie

4

Questo potrebbe non essere utile in questo contesto, ma ho pensato che vorrei aggiungere questo. Hai anche la possibilità di ordinarlo nella scrittura che tende ad essere migliore per le collezioni denormalizzate in cui non devi ordinare in più di un modo.

Ho trovato questa situazione nella mia app durante la creazione di un feed su un utente.

Meteor.users.helpers({ 
    'addToFeed': function (gameId, pushData) { 
    check(pushData, FeedSchema); 
    Meteor.users.update({ 
     _id: this._id, 
     "games.gameId": gameId 
    }, { 
     $push: { 
     "games.$.feed": { 
      $each: [pushData], 
      $sort: { timestamp: -1 } 
     } 
     } 
    }); 
    } 
}); 

ho trovato ad essere piuttosto utile perché si può quindi utilizzare find() e saranno ordinati secondo la Sua specificazione per impostazione predefinita.

+0

Sto ricevendo un errore Minimongo su non essere in grado di impostare il campo denominato $ ... Qualche idea? Penso che questo sia davvero vicino a ciò che voglio – lol