使用猫鼬,我如何过滤然后分组?

时间:2014-08-03 06:31:45

标签: node.js mongodb mongoose

我正在使用mongoose,到目前为止,我使用的查询得到了基于docId的所有批评。我想现在用不同的编辑器对这个结果进行分组。除此之外,我的编辑是一个对象。

这就是我的批评查询:

 Critique.find({docId:req.params.docId}).populate('editor', 'name username').exec(function(err, critiques){
     if(err){
      console.error("Cannot find critiques with docId: " + critiques.docId);   
     }
        console.log(critiques);
        res.jsonp(critiques);
    });

这是我正在查询的模型:

var CritiqueSchema = new Schema({

    className : String,
    content: String,
    eleId: Number,
    type: String,
    comments: String,  
    isAccepted: Boolean,
    classes: String,
    docId:{
        type: Schema.ObjectId,
        ref: 'Composition'
    },
    created: {
        type: Date,
        default: Date.now
    },
    editor: {
        type: Schema.ObjectId,
        ref: 'User'
    },
});

更新新查询:

    Critique.aggregate(
   [ {$match : {docId : mongoose.Types.ObjectId(req.params.docId)}},
     {$group : { _id : "$editor", critiques: { $push: "$$ROOT" } } }
   ]).exec(function(error, result){
          if(!error)console.log(result);
        else console.log(error); 
    });

1 个答案:

答案 0 :(得分:3)

$group中您需要的是aggregation framework。但aggregationpopulation并不适用。因此,您有两个选项populate并通过编写循环自行对结果进行分组,或者您可以使用$group对它们进行分组,然后手动查询每个编辑器。第二个更好,因为editor查询不会重复,而在population中会出现重大的重复。

    Critique.aggregate(
   [{
      $match:
       {
         docId: ObjectId(req.params.docid)
       }
    }, 
     { $group : { _id : "$editor", critiques: { $push: "$$ROOT" } } }
   ],
    function(err,result){
         if(!err){
             /* result will be of the form:
                 [{_id:<an editor's objectid>,critiques:[{<critique1 document>},{<critique2 document>}...]}...]
             */
             //you will have to manually query for each distinct editor(result[i]._id) which sucks
             //because the call will be asynchronous in the loop and you can't send your response without using async library
             //another option would be to use the $in operator on an array of the distinct critiques: 
             var editors = result.map(function(x) { return x._id } );
             User.find({_id:{$in:editors}},{'username':1},function(err,editorDocs){
                    var editor_ids=editorDocs.map(function(x){return x._id})
                    var index;
                    for(var i=0;i<result.length;i++){
                      index=editor_ids.indexOf(result[i]._id);
                      result[i].editor=editorDocs[index].username;
                    }
                    //result is your final result. In the editor field of each object you will have the username of the editor
              }) 
         }
     })

检查$$ROOT {{1}}。