How to use mapreduce in mongoose / mongodb query subdocument?

I implemented a simple messaging system in mongoose / mongodb, the circuit is as follows

var schema = new mongoose.Schema({
    user: {type:String, required:true},
    updated: {type:Date, default:new Date()},       
    msgs: [ {m:String, // message itself 
             d:Date,   // date of message
             s: String,  // message sender
             r:Boolean   // read or not
            } ],
});

all messages are stored in a nested msg array, now I want to request messages from a specific sender, for example,

{
  "_id" : ObjectId("52c7cbe6d72ecb07f9bbc148"),
  'user':'abc'
  "msgs" : [{
      "m" : "I want to meet you",
      "d" : new Date("4/1/2014 08:52:54"),
      "s" : "user1",
      "r" : false,
      "_id" : ObjectId("52c7cbe69d09f89025000005")
    }, {
      "m" : "I want to meet you",
      "d" : new Date("4/1/2014 08:52:56"),
      "s" : "user1",
      "r" : false,
      "_id" : ObjectId("52c7cbe89d09f89025000006")
    }, {
      "m" : "I want to meet you",
      "d" : new Date("4/1/2014 08:52:58"),
      "s" : "user2",
      "r" : false,
      "_id" : ObjectId("52c7cbea9d09f89025000007")
    }
   }

Here I have a document for user 'aa', which has three messages, two messages from user1, and one message from user2. And I want to request messages from 'user1'

Basically, there are two ways to do this: reduce or compile the map. I tried the solution to reduce the map.

var o = {}; 
o.map = function() { 
    this.msgs.forEach(function(msg){ 
        if(msg.s == person){  emit( msg.s, {m:msg.m,d:msg.d,r:msg.r}); }
    })
}       
o.reduce = function(key, values) {
    var msgs = [];
    for(var i=0;i<values.length;i++)
    msgs.push(values[i]);       
    return JSON.stringify(msgs);
}
o.query  = {user:'username'};  
o.scope = {person:'user1'};
model.mapReduce(o,function (err, data, stats) { 
    console.log('map reduce took %d ms', stats.processtime)
    if(err) callback(err);
    else callback(null,data);
})

Ultimately, he works with results such as

 [ 
    { _id: 'helxsz',
    value: '[
        {"m":"I want to meet you","d":"2014-01-04T08:52:54.112Z","r":false}, ....
        ]
 ]

The result is what I want, but the format is a bit complicated. How can I change the output format like this

    { sender: 'helxsz',
      messages: '[
        {"m":"I want to meet you","d":"2014-01-04T08:52:54.112Z","r":false}, ...
        ]
    }

, ?

28 . , msg 4- . 28 , , "".

+4
2

, , , . title, className start, . mapReduce . ( mapReduce )

  db.events.aggregate([{
       $project: {
        title: "$value",
        className: "$_id.method",
        start: "$_id.time",
        _id:0 }
   }]
)
0

,

emit (msg.s, {m: msg.m, d: msg.d, r: msg.r});

:

 emit( sender: msg.s, messages: {m:msg.m,d:msg.d,r:msg.r});
-1

All Articles