Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB full text search and multiple words sorted by relevance

I have the following full text search query example:

db.collection.find({ $text: { $search: "dog cat" } })

This will return documents containing dog OR cat, but I would like to sort the results by relevance:

  • results containg all of the search words should be listed first,
  • followed by the ones containing only one of the search words.

Of course I'm looking for a solution that works with 3 or more search words as well.

I found that there is an aggreagation pipeline in MongoDB, maybe it's too late and my brain is fried, but couldn't figure out how I could use it in this case.

--- SOLUTION in Node.js and MongoJS ---

Just to keep everything in one place for future reference, Tug Grall's solution implemented in Node.js / MongoJS:

.get(function(req, res) {
    db.docs.find({ $text: { $search: req.query.q } }, {score : { $meta: "textScore" } })
    .sort( { score: { $meta: "textScore" } }, function(err, results) {
        if (err) {
            res.send(err);
        } else {
            res.json(results);
        }
    } );
});
like image 264
orszaczky Avatar asked Aug 26 '14 04:08

orszaczky


People also ask

Does MongoDB offer a full-text search solution for Atlas?

MongoDB offers a full-text search solution, MongoDB Atlas Search, for data hosted on MongoDB Atlas. Users running self-managed MongoDB deployments have access to on-premises text search capabilities. This page describes $text operator for self-managed deployments. $text performs a text search on the content of the fields indexed with a text index.

How do I do a full text search in MongoDB?

To do a full-text search, you start by indexing your data. Once the text index is created, you can perform a full-text search on your data. In MongoDB, you can use an aggregation pipeline with a $search stage to query the data.

How does the $text operator work in MongoDB?

The $text operator accepts a text query document with the following fields: A string of terms that MongoDB parses and uses to query the text index. MongoDB performs a logical OR search of the terms unless specified as a phrase. See Behavior for more information on the field.

How to search against a string field in MongoDB?

As MongoDB is a document-oriented NoSQL database, it’s common to store plain text in some fields. To search against a string field, we can use the regular expression operator $regex directly. However, $regex can only work for simple search queries and cannot use indexes efficiently. In MongoDB, there are better ways to search against string fields.


1 Answers

In MongoDB 2.6.x you can use the $meta textScore in the sort directly in the query:

db.docs.find( { $text : {$search : "dog cat"}  } , 
              {score : { $meta: "textScore" } }   
             ).sort( { score: { $meta: "textScore" } } )

The results are sorted by relevance:

 db.docs.find( { $text : {$search : "dogs cat"}  } , 
                {score : { $meta: "textScore" } }   
               ).sort( { score: { $meta: "textScore" } } )

  { "_id" : "3", "text" : "I like dogs and cats", "score" : 1.3333333333333333 }
  { "_id" : "4", "text" : "I like dogs. But I do not like cats", "score" : 1.25 }
  { "_id" : "1", "text" : "I like dogs", "score" : 0.75 }
  { "_id" : "2", "text" : "I like cats", "score" : 0.75 }
like image 83
Tug Grall Avatar answered Oct 06 '22 14:10

Tug Grall