Full text search with weight in mongoose

MongodbMongooseFull Text-Search

Mongodb Problem Overview


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 https://www.npmjs.org/package/mongoose-text-search">mongoose-text-search</a>;? How about without weight?
And how should I do it?

Mongodb Solutions


Solution 1 - Mongodb

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

Solution 2 - Mongodb

As of MongoDB 2.6, a collection can have at most one text index (documented here). Therefore, you will not be able to do what you want with the current version of MongoDB. Really, for complicated text searching problems with requirements of different weights depending on the location of the match, you should consider a full-blown text searching solution like Solr or ElasticSearch.

As a workaround in MongoDB, you could tokenize the fields manually, store them as keyword arrays, and index them:

animal: ["The", "quick", "brown", "fox", "jump", ..., "dog"]

then a query like

db.test.find({animal: {$in: ["brown", "shoes"]})

mimics text search. There are a few limitations of this approach like the manual work required to set it up, the fact that there will be no stemming to, e.g., match "dreaming" with "dream", the fact that stopwords will not be removed like in a normal text index, and the absence of any weighting mechanism.

Solution 3 - Mongodb

I found the following article that led me to the http://code.tutsplus.com/tutorials/full-text-search-in-mongodb--cms-24835 I dropped the index created in the top answer using the following

db.tablename.dropIndex({"indexname_text"})  

I got the list of indexes with this command

db.tablename.getIndexes()

I then used the following to create the indexes

db.tablename.createIndex({"$**":"text"})

the following commands worked in Mongoose

model.find(
    {$text: {$search: "text you are searching for"}},
    {score: {$meta: "textScore"}})
    .sort({score:{$meta:"textScore"}}
)
.exec(function(err, results) {
    `enter code here`if(!err){
    console.log('results ' + results);
}
else
{
    console.log(err);
}
});

Solution 4 - Mongodb

	var searchQuery=new RegExp('dam', 'i');
	var query = { firstName : searchQuery };
    Model.find(query ...

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFoad Nosrati HabibiView Question on Stackoverflow
Solution 1 - MongodbeagorView Answer on Stackoverflow
Solution 2 - MongodbwdberkeleyView Answer on Stackoverflow
Solution 3 - MongodbGordon DeudneyView Answer on Stackoverflow
Solution 4 - Mongodbdam1View Answer on Stackoverflow