2015-04-02 14 views
5

Sto lavorando al sistema di messaggi e ho bisogno di ottenere l'ultimo messaggio da ciascun utente che ha inviato un messaggio all'utente registrato. Ho questa struttura in MongoDB:Mangusta - trova l'ultimo messaggio da ciascun utente

[{ 
    "_id": "551bd621bb5895e4109bc3ce", 
    "from": "admin", 
    "to": "user1", 
    "message": "message1", 
    "created": "2015-04-01T11:27:29.671Z" 
}, { 
    "_id": "551bd9acf26208ac1d9b831d", 
    "from": "user1", 
    "to": "admin", 
    "message": "message2", 
    "created": "2015-04-01T11:42:36.936Z" 
}, { 
    "_id": "551bdd6d849d53001dd8a64a", 
    "from": "user1", 
    "to": "user2", 
    "message": "message3", 
    "created": "2015-04-01T11:58:37.858Z" 
}, { 
    "_id": "551bdd99849d53001dd8a64b", 
    "from": "user2", 
    "to": "admin", 
    "__v": 0, 
    "message": "message4", 
    "created": "2015-04-01T11:59:21.005Z" 
}, { 
    "_id": "551bdda1849d53001dd8a64c", 
    "from": "user1", 
    "to": "admin", 
    "__v": 0, 
    "message": "message5", 
    "created": "2015-04-01T11:59:29.971Z" 
}] 

ho bisogno di ottenere i campi from, message e created da ultimo messaggio di ogni utente che ha inviato messaggio a utente registrato. Ho provato ad usare distinti ma restituisce solo un campo. Ho questo:

Message.find({ 
     to: req.user.username 
    }) 
    .select('message created') 
    .sort('-created') 
    .exec(function (err, messages) { 
     if (err) { 
      return res.status(400).send({ 
       message: getErrorMessage(err) 
      }); 
     } else { 
      res.json(messages) 
     } 
    }); 

ma restituisce tutti gli utenti che hanno inviato messaggi a utente connesso e ho bisogno di avere solo gli utenti unici e il loro ultimo messaggio. C'è un modo come farlo con mangusta?

+0

possibile duplicato di [ Query di Mongodb: ultimo record per data per ciascun articolo] (http://stackoverflow.com/questions/29368141/mongodb-query-latest-record-by-date-for-each-item) – Dineshaws

risposta

7

Usa quadro di aggregazione dove i vostri stadi della pipeline hanno $match, $sort, $group e $project espressioni:

Message.aggregate(
    [ 
     // Matching pipeline, similar to find 
     { 
      "$match": { 
       "to": req.user.username 
      } 
     }, 
     // Sorting pipeline 
     { 
      "$sort": { 
       "created": -1 
      } 
     }, 
     // Grouping pipeline 
     { 
      "$group": { 
       "_id": "$from", 
       "message": { 
        "$first": "$message" 
       }, 
       "created": { 
        "$first": "$created" 
       } 
      } 
     }, 
     // Project pipeline, similar to select 
     { 
      "$project": { 
       "_id": 0, 
       "from": "$_id", 
       "message": 1, 
       "created": 1 
      } 
     } 
    ], 
    function(err, messages) { 
     // Result is an array of documents 
     if (err) { 
      return res.status(400).send({ 
       message: getErrorMessage(err) 
      }); 
     } else { 
      res.json(messages) 
     } 
    } 
); 

If req.user.username = "admin", con la vostra raccolta di campioni, allora il risultato è:

{ 
    "result" : [ 
     { 
      "message" : "message4", 
      "created" : "2015-04-01T11:59:21.005Z", 
      "from" : "user2" 
     }, 
     { 
      "message" : "message5", 
      "created" : "2015-04-01T11:59:29.971Z", 
      "from" : "user1" 
     } 
    ], 
    "ok" : 1 
} 
+2

Impressionante, grazie tu! –

Problemi correlati