Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

custom sort for a mongodb collection in meteor

I have this collection of products and i want to display a top 10 products based on a custom sort function

[{ _id: 1, title, tags:['a'], createdAt:ISODate("2016-01-28T00:00:00Z") } ,
{ _id: 2, title, tags:['d','a','e'], createdAt:ISODate("2016-01-24T00:00:00Z") }]

What i want to do is to sort it based on a "magic score" that can be calculated. For example, based on this formula: tag_count*5 - number_of_days_since_it_was_created.

If the first one is 1 day old, this makes the score:

[{_id:1 , score: 4}, {_id:2, score: 10}]

I have a few ideas on how i can achieve this, but i'm not sure how good they are, especially since i'm new to both mongo and meteor:

  1. start an observer (Meteor.observe) and every time a document is modified (or a new one created), recalculate the score and update it on the collection itself. If i do this, i could just use $orderBy where i need it.

  2. after some reading i discovered that mongo aggregate or map_reduce could help me achieve the same result, but as far as i found out, meteor doesn't support it directly

  3. sort the collection on the client side as an array, but using this method i'm not sure how it will behave with pagination (considering that i subscribe to a limited number of documents)

Thank you for any information you can share with me!

like image 347
Radu Bogdan Avatar asked Feb 01 '16 22:02

Radu Bogdan


People also ask

How do I sort a MongoDB collection in descending order?

Ascending/Descending SortSpecify in the sort parameter the field or fields to sort by and a value of 1 or -1 to specify an ascending or descending sort respectively. When comparing values of different BSON types, MongoDB uses the following comparison order, from lowest to highest: MinKey (internal type) Null.

What is the use of sort () in MongoDB?

This operation sorts the documents in the users collection, in descending order according by the age field and then in ascending order according to the value in the posts field.

Does MongoDB support sorting?

MongoDB may use multiple indexes to support a sort operation if the sort uses the same indexes as the query predicate. If MongoDB cannot use an index or indexes to obtain the sort order, MongoDB must perform a blocking sort operation on the data.


1 Answers

Literal function sorting is just being implemented in meteor, so you should be able to do something like

Products.find({}, {sort: scoreComparator});

in an upcoming release.

You can use the transform property when creating collection. In this transform, store the magic operation as a function.

score=function(){
    // return some score
};
transformer=function(product){
  product.score=score; 
  // one could also use prototypal inheritance 
};
Products=new Meteor.Collection('products',{transform:transformer});

Unfortunately, you cannot yet use the sort operator on virtual fields, because minimongo does not support it.

So the ultimate fall-back as you mentioned while nor the virtual field sorting nor the literate function sorting are supported in minimongo is client side sorting :

// Later, within some template 
scoreComparator=function(prd1,prd2){
  return prd1.score()-prd2.score(); 
}
Template.myTemplate.helpers({
  products:function(){
    return Products.find().fetch().sort(scoreComparator);
  }
});

i'm not sure how it will behave with pagination (considering that i subscribe to a limited number of documents)

EDIT : the score will be computed among the subscribed documents, indeed.

like image 138
Jules Sam. Randolph Avatar answered Sep 29 '22 10:09

Jules Sam. Randolph