Search code examples
.netelasticsearchnest

How to make a Nest Elasticsearch case insensitive


I'm using the Nest.ElasticSearch library for .Net

And i have a model that i use for the index, which has a field i want to sort alphabetically (A-Z)

    [Text(Fielddata = true, Analyzer = "keyword")]
    public string FieldToSort { get; set; }

Then i have an endpoint i call which will make use of Nest.ElasticClient

        if (sortProperty != null)
        {
            SortOrder sortOrder = sortValue != null && sortValue.ToLower() == "asc" ? SortOrder.Ascending : SortOrder.Descending;

            switch (sortProperty.ToLower())
            {
                case "fieldToSort":
                    sortDescriptor.Field(s => s.FieldToSort , sortOrder);
                    break;
            }
        }
        var response = _client.Search<FieldModel>
           (
               s => s.Index("indexName")
               .Query(q => q
                   .Bool(b => b
                       .Filter(filterDescriptor)
                       .Must(sh => string.IsNullOrWhiteSpace(query) ? sh.MatchAll() : sh
                           .MultiMatch(mm => mm
                               .Fields(f => f
                                   .Field(c => c.something, 1)
                                   .Field(c => c.somehingelse, 3)
                               .Query(query)
                               .Operator(Operator.And)
                           )
                       )
                   )
               )
               .TrackTotalHits(true)
               .MinScore(Config.ElasticSearch.MinScore)
               .Sort(so => sortDescriptor)
               .Skip(offset)
               .Take(pageSize)
           );

The problem is that when i get the list it seems to order A-Za-z, what if i want this to be case insensitive, so it doesn't take in account if it's Capital or lowercase?


Solution

  • You should be doing this at index time for best performance. You can define a lowercased normalizer in your index settings:

    .Normalizers(norm => norm.Custom("lowercase", cn => cn.Filters("lowercase"));
    

    Then define this in your mapping. If you are using attribute based mapping it would look like this:

    [Keyword(Index = true, Normalizer = "lowercase")]
    

    Syntax might differ slightly depending on your ES and NEST version, but this would be the general approach.