Full text search with weight in mongoose

Foad Nosrati Habibi picture Foad Nosrati Habibi · Jul 12, 2014 · Viewed 41.5k times · Source

As I find out, since version 3.8.9, mongoose support full text search. But I can't find a good documentation for it!
I want to do something like:

db.collection.ensureIndex(
    // Fields to index
    {
        animal:  "text",
        color:   "text",
        pattern: "text",
        size:    "text"
    },

    // Options
    {
        name: "best_match_index",

        // Adjust field weights (default is 1)
        weights: {
            animal: 5,  // Most relevant search field
            size:   4   // Also relevant
       }
    }
)

Can I do it with pure mongoose? Or I have to use some plugin like mongoose-text-search? How about without weight?
And how should I do it?

Answer

eagor picture eagor · Aug 26, 2014

Yes, you can use full text search in Mongoose >= 3.8.9. Firstly, a collection can have at most one text index (see docs). So, to define text index for several fields, you need compound index:

schema.index({ animal: 'text', color: 'text', pattern: 'text', size: 'text' });

Now you can use $text query operator like this:

Model
    .find(
        { $text : { $search : "text to look for" } }, 
        { score : { $meta: "textScore" } }
    )
    .sort({ score : { $meta : 'textScore' } })
    .exec(function(err, results) {
        // callback
    });

This will also sort results by relevance score.

As for weights, you can try to pass weights options object to index() method (where you define compound index) (working at least with v4.0.1 of mongoose):

schema.index({ animal: 'text', color: 'text', pattern: 'text', size: 'text' }, {name: 'My text index', weights: {animal: 10, color: 4, pattern: 2, size: 1}});