对于具有不同条件的同一查询,我如何db.collection.count()?

时间:2014-02-25 11:54:03

标签: javascript mongodb aggregation-framework

我可以使用单个查询而不是多次计数查询来获取下面三个范围的计数吗?

db.ARTDocument.count({'latestResult.boostedResult.relevancy': {$lt:40}})
db.ARTDocument.count({'latestResult.boostedResult.relevancy': {$gt:40,$lt:60}})
db.ARTDocument.count({'latestResult.boostedResult.relevancy': {$gt:60}})

3 个答案:

答案 0 :(得分:1)

如果您真的只想要一个查询,可以调用db.eval()(确保满足性能要求)。在eval中,您运行db.find()以查找几乎所有记录(我已添加$exist测试以防万一。然后您检查它在< 40 < 60范围内的每个记录。像这样:

db.eval(function() {
    var lt40 = 0, gt40lt60 = 0, gt60 = 0, r;
    db.ARTDocument.find({'latestResult.boostedResult.relevancy': {$exists:1}}).forEach(function(doc) {
        r = doc.latestResult.boostedResult.relevancy;
        if (r < 40) {
            lt40 ++;
        } else {
            r < 60 ? gt40lt60++ : gt60++
        }    
    });
    return {
        lt40: lt40,
        gt40lt60: gt40lt60,
        gt60: gt60
    }    
});

最后,您将返回包含三个计数的记录。

答案 1 :(得分:1)

可能mapReduce不是吗? 我怀疑这会比db.eval更好,因为它会正确使用分片。

mapper=function(){
    if (this.latestResult.boostedResult.relevancy >40){
        emit('lt40', {'count':1});
    }
    if (this.latestResult.boostedResult.relevancy > 40 && this.latestResult.boostedResult.relevancy<60){
        emit('middle', {'count':1});
    }
    if (this.latestResult.boostedResult.relevancy >60){
        emit('gt60', {'count':1});
    }
}


reducer=function(k,v){
    counter=0;
    for (i=0;i<v.length;i++){
        counter+=v[i].count;
    }
    return {'count':counter}
}
db.ArtCategories.mapReduce(mapper, reducer, {out:{inline:1}})

这应该会将结果分解为类别

答案 2 :(得分:0)

我们可以考虑这而不是mapReduce吗?

db.ARTDocument.aggregate([
{"$group": {
  "_id": {"$cond": [
      {"$lte": ["$latestResult.boostedResult.relevancy", 40] },
      "Lowest",                                  
      {"$cond": [
          {"$and": [
              {"$gt": ["$latestResult.boostedResult.relevancy", 40] },
              {"$lte": ["$latestResult.boostedResult.relevancy", 60] }
          ]},
          "Medium",
         {"$cond": [
             {"$and": [
                 {"$gt": ["$latestResult.boostedResult.relevancy", 60] },
                 {"$lte": ["$latestResult.boostedResult.relevancy", 80 ] }
             ]},
             "Higher",
               "Highest"
         ]}
     ]}
 ]},
 "count": {"$sum": 1}
   }},
   {"$sort": { "count": 1 }}
])