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


  • 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.

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

1 Like

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: