[solved] Filter documents - How to do this efficiently?


#1

Situation

  • I have a Products Collection.
  • Products have a price (number), a category (string) and a expiry date (date) attached to them.
  • I display the products like so:

return Products.find({}, {sort: {createdAt: -1}});;

Goal: Implement filtering

For example: Only show products that have a price below $100.
To do this I store the current value from a clicked button in a Session.

The Button:

<div class="button--filter" data-filter="4500">Price: below $4500</div>

The Event:

'click .button--filter': function(event) {
    var filter = event.target.getAttribute('data-filter');

    Session.set('filter', filter);
}
//returns '4500'

Problem: Efficiency

Now I could mak this work by writing a ton of if-else-statements like so:

var filter = Session.get('filter');

if (filter == 4500) {
	return Products.find({price: {$gt: 4500}}, {sort: {createdAt: -1}});
} else if (filter == 3500) {
	return Products.find({price: {$gt: 3500}}, {sort: {createdAt: -1}});
} else {
	return Products.find({}, {sort: {createdAt: -1}});
};

Obviously this is not really the best approach.
How can I make this more efficient?

#Steps Taken
I’ve tried to always store the whole find() parameter in the session like so:

Set Session:

click .button--filter': function(event) {
    var filter = event.target.getAttribute('data-filter');
        
    Session.set('filter', 'price: {$gt: ' + filter + '}');
}
// returns 'price: {$gt:4500}'

Get Session:

var filter = Session.get('filter');
return Products.find({filter}, {sort: {createdAt: -1}});

But this is not working.
As far as I understand the Session returns a string.
But the find() method expects an object.

Any help would be appreciated.


#2

Session can hold an object too, it is just you who is forcing it to be string.
Normally you would do Session.set(‘filter’, { price: {$gt: filter} } );
And than use it Products.find( Session.get(‘filter’)}, {sort: {createdAt: -1}});


#3

Hey @shock,

many thanks for your reply. Of course it was a super simple solution :smiley:

I implemented it like so:

The Button:

<div class="filter--price" data-filter="4500">$4500 max</div>

The Event:

'click .filter--price': function(event) {
    var filter = event.target.getAttribute('data-filter');
    var filterNum = parseInt(filter);

    Session.set('filter', {price: {$lte: filterNum}});
}  

The Helper:

var filter = Session.get('filter');

if (filter != null) {
    return Products.find(filter, {sort: {createdAt: -1}});
} else {
    return Products.find({}, {sort: {createdAt: -1}});
};

Somehow you can probably do this without any if else statement in the helper, but I couldnt figure out how.
I think this solution is good enough.

Again: Thanks for our help! :smile: