Reputation: 15675
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);
}
} );
});
Upvotes: 8
Views: 5070
Reputation: 3510
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 }
Upvotes: 12