Thank you! Your feedback has been delivered
Thank you! Your feedback has been sent

Meteor: Create filters for a collection server side and store them in a local collection. Good idea?

We have pretty big sets of documents that we want our users to be able to view and filter. To speed things up we're only sending a limited amount of documents down to the client. However, since we do need the clients to be able to filter the documents we need a way to send down the keys and values they can filter on. Based on the clients selection of filters we create a query for the documents. Say for instance that we have two documents like this:

{tags: ['foo'], user: 'Ken'}
{tags: ['bar', 'baz'], user: 'Barbie'}

In this case, the client should see that tags can be filtered on foo, bar and baz while user can be filtered on Ken and Barbie. Since the filters are just an aggregation of the data in the documents I dont want to create a collection for the filters and store it in the db. Instead I've been playing around with using

var Filters = new Meteor.Collection(null) 

inside a publication. I query all documents I want to create filters for and then I insert the filters to the Filters collection. Using .observe on the Filters collection i send down the filters to the client as they get added.

The result of this is that each client creates a Filters collection on the server. Say that each of those collections contain about 50-400 filters like {tag: 'foo', count: 3}. To me that sounds as if it should be fine without draining the ram of the server, but I'm no computer scientist. Any input on this would be appreciated.

If you have any other ideas of how to create filters on the server would also be interesting to look at.

Thanks!

Note This questions has been copied from Stack Overflow. Posted by datacarl. The bounty is provided by CodersClan.

User Gravatar

CodersClan-Team

Posted Nov 7 2013 4:06 UTC

$25


  • meteor
  • 3764 Views

3 Replies


How about you publish the entire collection with just the filter fields, using field specifiers? That way it's just like an extra collection with just the filters, and in the results you can choose to only display documents that don't just have a tag field.

However a better idea, in my opinion, is to do something similar to mohamed's suggestion, and normalize things a bit. Have a separate Tags collection that contains a tag name and id, and have a TagsUsers connection that stores the tag id and user id. That will make filtering much easier, because then you can simply publish the tags collection to the client, add/delete/edit tags only once, and easily filter the publish method on the server.

// Server publish method
// Return just users that the client has filtered
Meteor.publish('users', function (tagIds) { // tags is an array of tag ids ['foo', 'baz']
    var userIds = TagsUsers.find({ tagId: { $in: tagIds } }).map(function (connector) {
        return connector.userId;
    });

    return Users.find({ _id: {$in: userIds } });
});

// Client subscribe method
Meteor.subscribe('users', Session.get('tag-filters'));
User Gravatar

BenjaminRH

Posted Nov 7 2013 4:07 UTC

You could try creating a virtual collection on the server the same way on the client and just send that down, or at least thats one option you have.

Client Side:

var Filters = new Meteor.Collection("filters");

Server Side:

Meteor.publish("filters", function(tags) {
    var results = Tags.find({tags: {$in : tags } }).fetch();
    var l = results.length;
    while(l--) {
        var custom_filter_data = {test: "value"}
        this.added("filters", l,  custom_filter_data);
    }

    this.ready()
}); 
User Gravatar

Akshat

Posted Nov 7 2013 11:48 UTC

I've developed a smart package that with the intention to solve this easly. Please, take a look and let me know it was useful. https://github.com/julianmontagna/filter-collections

User Gravatar

user945

Posted Jan 6 2014 1:49 UTC

Add a reply

By posting a reply on CodersClan you agree to our Terms & Conditions