There are several ways to solve this problem. The solution I will focus on is using the mongodb aggregation structure. Firstly, here is the aggregation pipeline that will solve your problem, after which there will be an explanation / breakdown of what is happening in the team.
db.testagg.aggregate( { $unwind : '$likes' }, { $group : { _id : '$_id', numlikes : { $sum : 1 }}}, { $sort : { 'numlikes' : 1}})
This pipeline has three main commands:
1) Defrost: this divides the “likes” field, so there is one element “per document”
2) Group: this groups the document using the _id field, increasing the number of numLikes for each document found. This will cause numLikes to be filled with a number equal to the number of items that were “liked” before
3) Sort: Finally, we sort the return values in ascending order based on numLikes. In the test, I executed the output of this command:
{"result" : [ { "_id" : 1, "numlikes" : 1 }, { "_id" : 2, "numlikes" : 2 }, { "_id" : 3, "numlikes" : 3 }, { "_id" : 4, "numlikes" : 4 }....
This is for data inserted through:
for (var i=0; i < 100; i++) { db.testagg.insert({_id : i}) for (var j=0; j < i; j++) { db.testagg.update({_id : i}, {'$push' : {'likes' : j}}) } }
Please note that this does not fully answer your question, as this avoids the question of choosing a date range, but it will hopefully make you start and move in the right direction.
Of course, there are other ways to solve this problem. One solution could simply be to do all the sorting and manipulation on the client side. This is just one way to get the information you want.
EDIT: if you find this somewhat tedious, there is a ticket to add a size operator to the aggregation structure, I invite you to look and potentially increase it to try to speed up the addition of this new operator if you are interested.
https://jira.mongodb.org/browse/SERVER-4899