ninjanye / SearchExtensions

Library of IQueryable extension methods to perform searching
MIT License
331 stars 52 forks source link

How to perform a case insensitive search? #42

Open boop5 opened 4 years ago

boop5 commented 4 years ago

I want to ignore the case when using Containg or ContainigAll. But SetCulture is not available. Is the documentation outdated or am I doing something wrong?

Simplified example of what I'm doing

var searchTerms = new string[] { "mockingbird", "kill" }
var found = await books.Search(book => book.Title)
                       .ContainingAll(searchTerms)
                       .ToListAsync(stoppingToken);

I'm searching on an EfCore DbSet which inherits from IQueryable

ninjanye commented 4 years ago

Hi @boop5

Apologies for the delay in responding to this... What is it you are currently trying, using your example above you should be able to do the following... The important thing is to use SetCulture before the containing command

var searchTerms = new string[] { "mockingbird", "kill" }
var found = await books.Search(book => book.Title)
                       .SetCulture(StringComparison.OrdinalIgnoreCase)
                       .ContainingAll(searchTerms)
                       .ToListAsync(stoppingToken);
ninjanye commented 4 years ago

Hi @boop5,

Was just looking back on this and I think I now understand the issue. For IEnumerable<T> the .SetCulture method is available, however, when used with SQLServer the default is to perform a case insensitive string match, so SetCulture is not needed. This does raise the point, that just because someone is using IQueryable does not mean they have SqlServer as their backend store, so this is something I will look to add for IQueryable in the future

I will give this a couple of days, but otherwise assuming this addresses your point, I will close this down

wouter-b commented 2 years ago

Hi @ninjanye ,

that just because someone is using IQueryable does not mean they have SqlServer as their backend store, so this is something I will look to add for IQueryable in the future

I'm using CosmosDB as a backend, whcih is Case Sensitive by default. Adding .SetCulture to IQueryable would solve the case insensitive search for me.

RIght now my workaround is

var queryTerms = query.Trim().ToLower().Split(' '); return projects.Search( p => p.ProjectName.ToLower(), p => p.ClientName.ToLower(), p => p.Area.ToLower() ).ContainingAll(queryTerms);

Which is not optimal because it requires a scan instead of using an index.

jrodriguez-masao commented 2 years ago

Hello @ninjanye, I'm using SQLite (case-sensitive by default) as a backend an it would also be really useful to have .SetCulture for IQueryable. Have you got any timeline on this implementation, or any way we can help make it happen?