Search code examples
c#elasticsearchnest

Elastic search Nest C# - Is it possible a case insensitive sort on a string field through automap


I have a elasticsearch Nest Model class

public class Data
    {       
        public long Id { get; set; }
       
        public string DeviceCode { get; set; }
    }

When indexing this document using automap , nest will create two fields for the property DeviceCode - DeviceCode and DeviceCode.keyword. I want to sort based on the DeviceCode.keyword field with case insensitive sorting - Is it possible to acheive this through automap (by applying analyser or filter using attribute mapping in the model class). I want to keep both text and keyword fields in elastic search.

Regards Vineeth


Solution

  • It's possible to apply a normalizer to a keyword field to lowercase values at index time for case-insensitive querying and aggregations

    var client = new ElasticClient(settings);
        
    var createIndexResponse = client.Indices.Create("my-data", c => c
        .Settings(s => s
            .Analysis(a => a
                .Normalizers(n => n
                    .Custom("lowercase", cn => cn
                        .Filters("lowercase")
                    )
                )
            )
        )
        .Map<Data>(m => m
            .AutoMap()
            .Properties(p => p
                .Text(t => t
                    .Name(n => n.DeviceCode)
                    .Fields(f => f
                        .Keyword(k => k
                            .Name("keyword")
                            .IgnoreAbove(256)
                        )
                        .Keyword(k => k
                            .Name("keyword_lowercase")
                            .Normalizer("lowercase")
                            .IgnoreAbove(256)
                        )
                    )
                )
            )
        )
    );
    

    Then to use the keyword_lowercase multi-field

    var searchResponse = client.Search<Data>(s => s
        .Index("my-data")
        .Sort(so => so
            .Ascending(f => f.DeviceCode.Suffix("keyword_lowercase"))
        )
    );