Reputation: 1834
I'm trying to build a helper to create a dynamic search using Nest Elastic Search. The sorting works fine but it is also sorting based on casing. This is my generic Search
public virtual async Task<IEnumerable<T>> Search(ISearchQueryHelper<T> searchSpecs)
{
try
{
var request = new SearchRequest<T>(this.indexName)
{
Size = 5000,
Query = searchSpecs.GetQuery(),
Sort = searchSpecs.GetSorts()
};
var response = await elasticClient.SearchAsync<T>(request);
return response.Documents;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
throw;
}
}
and I'm indexing documents like this
public virtual async Task<string> IndexAsync(T document)
{
var response = await elasticClient.IndexAsync(document, idx => idx.Index(indexName));
if (response.Result == Result.Error)
{
throw response.OriginalException;
}
return response.Id;
}
And in my Helper class, I'm adding sorts like this
private List<ISort> Sorts { get; }
public void AddSort(Expression<Func<T, object>> field, bool isAscending)
{
Sorts.Add(new FieldSort
{
Field = Infer.Field<T>(field),
Order = isAscending ? SortOrder.Ascending : SortOrder.Descending
});
}
Is there a way to ignore case on sort? Something like StringComparison.CurrentCultureIgnoreCase
when comparing strings.
I've seen lots of thread about this but all of it are using Client.Indices.Create()
instead of Client.IndexAsync()
and all are class specific too which will require me to map every field I want to ignore case sort.
Upvotes: 0
Views: 270
Reputation: 1770
You want to sort Es side to win time, so you need to tell elastic how to analyse / sort your data.
You cant use default mappings analyser, as you notice, in order to dodge to create a new mappings for each index, you could use a generic function.
If you call analyser default, he will overwrite the default analyser, this is that you are looking for.
Call this function only 1 time, before indexing the first document, you can use Client.Indices.Exist to know if your index need to be created.
public void SetMapping<T>(string index) where T : class {
var re2 = Client.Indices.Create(index, c => c
.Map<T>(m => m
.Properties(ps => ps
)
.AutoMap()
)
.Settings(
s =>
s.Analysis(
a =>
a
.Analyzers(
an =>
an.Custom("default", cad =>
cad.Tokenizer("standard").Filters(new string[] {
"lowercase",
"asciifolding"
}))
)
)
)
);
}
note: Nest client is not perfect, for specific use like this, it could be easy to create your index using a json with lowlevelclient or a curl.
The post about the default mappins modification: Changing the default analyzer in ElasticSearch or LogStash
Upvotes: 1