Reputation: 999
I have a REST API
Call like /item/search
which has some query parameters attached to it.
The user can search for entire term
or just 3 or more characters
of a term.
The Node.JS
exports function is as follows,
exports.getSearchedItems = function(req,res){
var searchText = req.query.q;
var searchedString = searchText.replace(/ /g,"|");
var nameRegex = new RegExp('\\b' + searchedString + '.*', 'i');
Item.find()
.or([
{$text: {$search: searchText } },
{'name': {$regex: nameRegex } },
{'score':{'$meta': 'textScore'}
]
)
.sort({'score':{'$meta': 'textScore'}}
.exec(function(err, items){
if(err) console.log('Error Finding Query ' +err);
res.send(items);
});
};
A query Like item/search?q=new+2
,
We get the below Error,
Can't canonicalize query: BadValue must have $meta projection for all $meta sort keys
Is there any way I can do a partial OR
full search yet maintain the textScore and sort my resulting mongoose documents as per that score.
Cheers and Thanks in Advance.
Upvotes: 1
Views: 2329
Reputation: 103365
MongoDB's find()
method can take a second optional argument indicating which fields to return and in your case of $text
search, the special projection field $meta
allows you to get back the score of the matched document so that you can sort on it.
Try modifying your find()
query to include the query and the $meta
projection as the find()
arguments instead of the or()
method:
Item.find(
{
"$or":[ {"$text": {"$search": searchText } }, {"name": {"$regex": nameRegex } } ]
},
{
"score" : { "$meta" : "textScore"}
})
.sort({"score": { "$meta": "textScore"} })
.exec(function(err, items){
if(err) console.log("Error Finding Query " + err);
res.send(items);
});
Upvotes: 3