2

In a MongoDB query, I'm trying to match records that have a string field that contains a search term at the beginning of any word in that string. The regex works correctly on regex101.com.

/\bCh/i

Matching values:

Chia seeds

i like to eat Chia seeds

i like to eat chia seeds

However when I try the same in a MongoDB query, I get no matching records.

{
    "TenantNames" : /(\bSmith)/i
}

I also tried /(\bSmith.*)/i and /(\bSmith.*\b)/i but they both return no matching records as well. What am I missing?

I'm using the C# driver for building queries.

Community
  • 1
  • 1
Justin
  • 17,670
  • 38
  • 132
  • 201
  • 1
    A good way to debug this is to use the regex `.` Then if it doesn't match, then it's not the regex right ? It would be the usage, the quoting, the form your language expects. Stuff like that. –  Jul 11 '19 at 20:28
  • @sln . works. The closest I've gotten is /(?=.*Ch)/i, but it will return any strings that have the value "ch" in ANY part of the word instead of just the beginning, so too many results are returned. – Justin Jul 11 '19 at 20:51
  • Did you try `{ TenantNames: { $regex: /\bCh/i }` ? https://docs.mongodb.com/manual/reference/operator/query/regex/ –  Jul 11 '19 at 21:02

2 Answers2

1

Not sure, what might be the desired output, I'm guessing you may be trying to design an expression similar to:

.*\bChia\b.*

or:

.*\bSmith\b.*

Also not sure, how the i flag works in mongodb.


Based on this doc, maybe we might also want to use some different commands for this task such as:

{ name: { $regex: /.*\bSmith\b.*/, $options: 'i', $nin: [ 'TenantNames' ] } }

The expression is explained on the top right panel of this demo, if you wish to explore/simplify/modify it, and in this link, you can watch how it would match against some sample inputs step by step, if you like.

Reference

MongoDB C# Query for 'Like' on string

Community
  • 1
  • 1
Emma
  • 27,428
  • 11
  • 44
  • 69
  • 1
    @Emma "TenantNames" : /.*\bCh\b.*/i is returning 0 results. Let me try that other format, I'm using the C# driver for building queries but hopefully they have a way of generating that format. – Justin Jul 11 '19 at 20:45
  • 1
    I'm not able to generate that format w/the C# driver. Tried both builder.Regex(z => z.TenantNames, new BsonRegularExpression(regexString, "i")) and new BsonDocument { { "TenantNames", new BsonDocument { { "$regex", regexString }, { "$options", "i" } } } }; but it still translates to "TenantNames" : /.*\bCh\b.*/i – Justin Jul 11 '19 at 21:02
0

this is quite easily achieved by creating a text index and doing a $text search.

db.Property.createIndex({"TenantNames": "text"},{"background":false})
db.Property.find({
    "$text": {
        "$search": "smith",
        "$caseSensitive": false
    }
})

here's the c# code that generated the above queries. it uses my library MongoDB.Entities for brevity.

using MongoDB.Entities;
using System;

namespace StackOverflow
{
    public class Program
    {
        public class Property : Entity
        {
            public string TenantNames { get; set; }
        }

        private static void Main(string[] args)
        {
            new DB("test");

            DB.Index<Property>()
              .Key(p => p.TenantNames, KeyType.Text)
              .Option(o => o.Background = false)
              .Create();

            (new[] {
                new Property { TenantNames = "Maggie Smith" },
                new Property { TenantNames = "Smith Clein" },
                new Property { TenantNames = "marcus smith stein" },
                new Property { TenantNames = "Frank Bismith" }
            }).Save();

            var result = DB.SearchText<Property>("smith");

            foreach (var property in result)
            {
                Console.WriteLine(property.TenantNames);
            }

            Console.Read();
        }
    }
}
Dĵ ΝιΓΞΗΛψΚ
  • 5,068
  • 3
  • 13
  • 26