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:
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);
}
} );
});
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.
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.
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.
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.
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 }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With