2013-01-25 12 views
11

Sto provando a ordinare i dati per data prima e poi raggruppare su un altro campo. Non funziona per me.Quadro di aggregazione Mongo, Ordina e poi gruppo non funzionante

La domanda a cui sto cercando di rispondere è: selezionare il cid distinto più recente?

dato questi dati:

db.summary.save({"lid" : 5, "date" : 5, "cid" : 2, "circles" : [ 2 ] }) 
db.summary.save({"lid" : 2, "date" : 2, "cid" : 1, "circles" : [ 2 ] }) 
db.summary.save({"lid" : 4, "date" : 0, "cid" : 3, "circles" : [ 2 ] }) 
db.summary.save({"lid" : 3, "date" : 3, "cid" : 2, "circles" : [ 2 ] }) 
db.summary.save({"lid" : 1, "date" : 1, "cid" : 1, "circles" : [ 2 ] }) 

db.summary.aggregate({$match :{circles: 2}, $sort: {date: -1}, $group: {_id: '$cid'}}) 

sto facendo una partita di prima su cerchi, quindi una sorta sulla data, poi un gruppo su cid

Il risultato che sto ottenendo:

{ 
    "result" : [ 
     { 
      "_id" : 3 
     }, 
     { 
      "_id" : 1 
     }, 
     { 
      "_id" : 2 
     } 
    ], 
    "ok" : 1 
} 

Ecco la mia analisi:

prima di corrispondenza o l'ordinamento per data, i dati erano:

"lid" : 5, "date" : 5, "cid" : 2 
"lid" : 2, "date" : 2, "cid" : 1 
"lid" : 4, "date" : 0, "cid" : 3 
"lid" : 3, "date" : 3, "cid" : 2 
"lid" : 1, "date" : 1, "cid" : 1 

Dopo l'ordinamento per data, il set di dati sarebbe:

"lid" : 5, "date" : 5, "cid" : 2 
"lid" : 3, "date" : 3, "cid" : 2 
"lid" : 2, "date" : 2, "cid" : 1 
"lid" : 1, "date" : 1, "cid" : 1 
"lid" : 4, "date" : 0, "cid" : 3 

Così, dopo il raggruppamento, il risultato mi aspetto è:

{ 
    "result" : [ 
     { 
      "_id" : 2 
     }, 
     { 
      "_id" : 1 
     }, 
     { 
      "_id" : 3 
     } 
    ], 
    "ok" : 1 
} 

Quale query risolve il mio problema?

Perché la query corrente non funziona per me?

+0

I parametri della pipeline su "aggregato" devono essere inseriti in un array o passati come oggetti indipendenti anziché un unico oggetto grande. E la tua domanda parla del raggruppamento su 'cid', ma il comando si sta raggruppando in' $ date'. – JohnnyHK

+0

Quello era un errore di battitura. Dovrebbe essere $ group: {_id: '$ cid'} – ben39

risposta

17

Quando si $group dopo un $sort nella pipeline, l'ordinamento precedente viene perso. Si potrebbe fare qualcosa di simile invece in modo che la data che si desidera ordinare è disponibile dopo il raggruppamento:

db.summary.aggregate(
    {$match: {circles: 2}}, 
    {$group: {_id: '$cid', date: {$max: '$date'}}}, 
    {$sort: {date: -1}}); 

risultato:

[ { _id: 2, date: 5 }, 
    { _id: 1, date: 2 }, 
    { _id: 3, date: 0 } ] 

Aggiungi un $project alla fine della pipeline se vuoi rimodellare l'output.

+0

Grazie! Questo è esattamente quello che stavo cercando anche se l'ho già capito dal momento in cui hai risposto :) – ben39

+1

non dimenticare che se vuoi ordinare qualcosa sul gruppo $ devi includerlo nel $ sort con '_id .Data'. controlla http://stackoverflow.com/questions/21265170/mongodb-aggregation-sort-not-working – mwm

+2

"Quando si raggruppa $ dopo un ordinamento $ nella pipeline, l'ordinamento precedente viene perso." Questo non è proprio vero (probabilmente obsoleto). Non solo è possibile, ma è il modo preferito in quanto in questo modo l'ordinamento può utilizzare gli indici: https://docs.mongodb.com/manual/reference/operator/aggregation/sort/#sort-operator-and-performance – slouc

Problemi correlati