Take the 2-minute tour ×

I'm playing around with the idea of creating a global search that allows me to find any model in any of a number of collections by any of the model's attributes. For example:

I have the following collections:

  • Users
  • Applications
  • Roles

I don't know ahead of time what attributes each User, Applicaion and Role will have but for illustration purposes lets say I have:

  • User.name
  • User.last_name
  • User.email
  • Application.title
  • Application.description
  • Role.name
  • Role.description

Now, lets say I create a model called Site with a method called search. I want Site.search(term) to search through all the items in each collection where term matches any of the attributes. In essence, a global model search.

How would you suggest I approach this? I can brute-force it by iterating through all the collections' models and each model's attributes but that seems bloated and inefficient.

Any suggestions?

/// A few minutes later...

Here's a bit of code I tried just now:

find: function(query) {
    var results = {}; // variable to hold the results
    // iterate over the collections
    _.each(["users", "applications", "roles"], _.bind(function(collection){
        // I want the result to be grouped by type of model so I add arrays to the results object
        if ( !_.isUndefined(results[collection]) || !_.isArray(results[collection]) ) {
            results[collection] = [];
        // iterate over the collection's models
        _.each(this.get(collection).models, function(model){
            // iterate over each model's attributes
            _.each(model.attributes, function(value){
                // for now I'm only considering string searches
                if (_.isString(value)) {
                    // see if `query` is in the attribute's string/value
                    if (value.indexOf(query) > -1) {
                        // if so, push it into the result's collection arrray
        // a little cleanup
        results[collection] = _.compact(results[collection]);
        // remove empty arrays
        if (results[collection].length < 1) {
            delete results[collection];
    // return the results
    return results;

This yields the expected result and I suppose it works fine but it bothers me that I'm iterating over three arrays. there may not be another solution but I have a feeling there is. If anyone can suggest one, thank you! Meanwhile I'll keep researching.

Thank you!

share|improve this question
add comment

1 Answer

I would strongly discourage you from doing this, unless you have a very limited set of data and performance is not really a problem for you.

Iteration over everything is a no-no if you want to perform search. Search engines index data and make the process feasible. It is hard to build search, and there is no client-side library that does that effectively.

Which is why everybody is doing searching on the server. There exist easy (or sort of) to use search engines such as solr or the more recent and my personal preference elasticsearch. Presumably you already store your models/collections on the server, it should be trivial to also index them. Then searching becomes a question of making a REST call from your client.

share|improve this answer
We've had success with sphinx as well, pretty easy to get going. –  David Biehl Sep 15 '13 at 2:56
add comment

Your Answer


