Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB full text search

Tags:

c#

mongodb

Create index

db.MyCollection.createIndex({'$**': 'text'}, {name: 'FullTextIndex'})

Search for match

db.MyCollection.find({$text: {$search: 'myWord'}}).count()

Result is 1. for a filed which has value "myWord is here"

If I do regular search for selected fields as following, I get two records, one record has Name = "myWord is here" and second record has "myWord" in Details filed as "something here and myWord is here"

db.getCollection('MyCollection').find({  
     "$or":[{"Name":/myWord/i}, {"Details":/myWord/i}]
    }).sort({"Name": 1})

How can I recreate the index so that it search in all fields as SQL where any field like %searchText%

And Finally how can I write this search query in C# Driver

Update:


I further looked in to it. it is finding all results that has a search key with prefix and suffix spaces, but not part of the string in a word.

Example it is returning a record for a value "Hello myWord is here", but doesn't return "HellomyWord"

But according to this document, it has to support wildcard search. https://docs.mongodb.com/v3.0/reference/operator/query/text/

like image 396
HaBo Avatar asked May 17 '16 18:05

HaBo


2 Answers

Since I haven't found, much help with wildcard search/Full text search using Mongo, I have come up with a work around for my requirement.

foreach (var doc in batch)
  {
     if (custDictionary.ContainsKey(projectId))
        {
           string concatenatedCustomFields = custFieldsList.Aggregate(string.Empty,
                            (current, custField) =>
                                current +
                                (ds.Tables[0].Columns.Contains(custField)
                                    ? (ds.Tables[0].Rows[i][custField].GetType().Name == typeof(DBNull).Name
                                        ? string.Empty
                                        : ((string) ds.Tables[0].Rows[i][custField]).StripHtml())
                                    : string.Empty));

                        doc.Add("CustomFieldsConcatenated", concatenatedCustomFields);
        }
    i++;
 }

I read list of custom fields for each group of documents, then create a concatenated Mongo Field, then use Regex query on that field.

Then to improve the performance of the query added following index

  _mongoConnect.Database?.GetCollection<BsonDocument>("MyCollectionName")
                .Indexes.CreateOneAsync(new BsonDocument("CustomFieldsConcatenated", "hashed"), new CreateIndexOptions { Name = "CollectionName_FieldName_Index" });
like image 136
HaBo Avatar answered Oct 11 '22 13:10

HaBo


Note that wildcard characters can be included in Regex Searches but not in the full text search.

There is already a feature request ticket for this SERVER-10227. If this is an important feature for you,please upvote the ticket.

Further adding to your comment:

I further looked in to it. it is finding all results that has a search key with prefix and suffix spaces, but not part of the string in a word.

Example it is returning a record for a value "Hello myWord is here", but doesn't return "HellomyWord"

The $text operator matches on the complete stemmed word.There is no facility at present to deal with index positions in strings that return a meaningful value for a projection. In your use case, a search on the term "myWord" will not match "HellomyWord". However, it matches a document containing ,e.g, "hi myWord is here" or "myWord comes" etc.

For more information, please see the Match Operation page.

like image 39
Pooja Avatar answered Oct 11 '22 14:10

Pooja