Question

Can I use single query instead of multiple count queries to get the counts for the three ranges below?

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}})
Was it helpful?

Solution

If you really want just one query, you can call db.eval() (make sure that performance requirements are met). In the eval, you run db.find() to find practically all records (I've added an $exist test just in case. Then you check for each record where it falls in the < 40 < 60 range. Something like this:

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
    }    
});

Finally, you return a record with the three counts.

OTHER TIPS

Possible to mapReduce isn't it? I suspect this will be better than a db.eval as it will utilise shards properly.

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}})

This should give you the results broken down into the categories

Can we consider this instead of 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 }}
])
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top