I’m making a big Q&A website on Meteor and I really need a fast and comprehensive search capability there. So far I’ve found a few options for searching:
RegEx is an option I currently use but it has limitations.
I don’t like Spomet cause it has examples on CoffieScript which I don’t know. Also I’m not sure how it works and how well it supports non-english texts.
I don’t like using MongoDB 2.4 version of full text search cause it introduces a lot of strange code in my project and I’m not sure if it supports reactivity.
I’ve been trying to upgrade my MongoDB to 2.6 and create text index there. It had worked in one project I made before. All I needed is to create text index via mongo console and then in Meteor.publish do something like this:
It worked like a charm but I’m not sure if the same search query will work on client using minimongo. Will it work?
In that app it didn’t matter cause it was a simple app with only one publication. So I’d just used Records.find({}) on the client and it was good enough.
But in my new app I can have a multiple publications of the same collections available on the client at time so I need to use queries on client to get required subset of data.
Another question is how do I sort results by score? MongoDB 2.6 supports that using score projection. Here’s an example from their docs:
Using that code I’m getting an error Exception in queued task: MongoError: Can't canonicalize query: BadValue must have $meta projection for all $meta sort keys
Without sort modifier it works just fine and even sends score field to the client which is great. But I need sorting ability on the server or else searching relevant records with pagination won’t work.
Does anybody know why Meteor’s implementation with sort modifier containing $meta doesn’t work while the same query with .sort({ score: { $meta: 'textScore' }}) in mongo console works just fine? What’s so special in Meteor MongoDB driver’s implementation preventing that from working?
Hello,
Thanks for your interesting messages.
I am trying to do the same but also without success.
When I run int the meteor mongo shell: db.docs.find( { $text: { $search: "something" , $language: "en" } }, { score: { $meta: "textScore" } } ).sort( { score: { $meta: "textScore" } } );
It works perfectly.
But no way to make it run from within my meteor application.
Do you know how to do it ?
Thanks a lot.
Thomas
– Note, the call to create the text index is not within Meteor.
– Also, note that I sort on the Client for now.
Can I just write a collection_name.ensureIndex({filed_name: “text”}) on Meteor startup or something to add the necessary "tex"t index?
Also, right now for example, the “text” index in the collection I’m working from is called [Display_Name]. This [field] contains both ‘FirstName + ’ ’ + LastName’.
While performing this search, I only get a “score” : 0.75, and it only matches if I input in the search box either the ‘FirstName’ or ‘LastName’ of a user.
Can I change the matching percentage or sensitivity so I get a match on partials?
[UPDATE]
After reading the docs it seems you can only match on a whole word, multiple words, or even not on the presence of words, within a [field] – but not parts of a word.
For example, if the target [field] contains the name, ‘don jon’, if I $search ‘don’, that document will be found (probably with a score of 0.75). If I $search ‘jon’ the same thing will happen. but if I $search ‘do’ or $search ‘jo’ nothing will $match.
@aadams Are you sure that is sorting properly with the score for you? I am trying to do the exact same thing in Meteor but it is still ignoring the score while sorting.
In fact I can’t even see the score in the returned fields.
Alternatively, I think in order to use full text search you basically can’t use the version of mongo that’s packaged with meteor (this may have changed) but you can create a new mongo database, connect to it, and enable full-text search.
The $text operator uses the text index. The $regex don’t use the text index.
Also the query syntax is different. The $text query is like when you search something in Google.