I'm doing a POC using elasticsearch for my app
In the elasticsearch index, the property names of my documents are in PascalCase, but when I generate a query from the code it converts the properties names to be camelCase
I tried following the documentation on how to set custom serialization options, but it does not work for me.
This is how I create the ElasticsearchClient in my Startup.cs file:
services.AddSingleton<ElasticsearchClient>(x => GetElasticsearchClient());
...
private ElasticsearchClient GetElasticsearchClient()
{
var uri = new Uri("my-deployment-uri");
var settings = new ElasticsearchClientSettings(
new SingleNodePool(uri),
sourceSerializer: (defaultSerializer, settings) =>
new DefaultSourceSerializer(settings, o => o.PropertyNamingPolicy = null))
.Authentication(new ElasticsearchApiKey("my-api-key"))
.EnableDebugMode();
return new ElasticsearchClient(settings);
}
And this is a usage example:
public class TestDocument
{
public int MyProperty { get; set; }
}
public class ElasticSearchFetcher
{
private readonly ElasticsearchClient _elasticsearchClient;
public ElasticSearchFetcher(ElasticsearchClient elasticsearchClient)
{
_elasticsearchClient = elasticsearchClient;
}
public async Task<List<TestDocument>> GetDocumentsAsync(int propValue)
{
var searchResponse = await _elasticsearchClient.SearchAsync<TestDocument>("test", s => s
.Query(q => q
.Match(m => m
.Field(f => f.MyProperty).Query(propValue))))
.ConfigureAwait(false);
var requestJson = searchResponse.ApiCallDetails?.RequestBodyInBytes != null
? Encoding.UTF8.GetString(searchResponse.ApiCallDetails.RequestBodyInBytes)
: null;
if (searchResponse.IsValidResponse)
{
var hits = searchResponse.Hits;
return hits.Select(h => h.Source).ToList();
}
return null;
}
}
If I debug and look at the value of "requestJson" this is what I see:
{
"query": {
"match": {
"myProperty": {
"query": 1
}
}
}
}
But I expect the property name to be "MyProperty" and not "myProperty", and this issue causes the elasticsearch to always return 0 results
Any idea why doesn't it work? I tried asking ChatGPT which gave me a couple of solutions but none worked (basically gave me the same solution in a more complex way - tried to create a custom source serializer with the options I want instead of the DefaultSourceSerializer, but it still didn't work)
Also worth mentioning:
Thanks to Ralf I found the answer using the DefaultFieldNameInferrer
It was a bit trickier finding how to change the DefaultFieldNameInferrer in the new version since there was no documentation for it and it's a read-only property of the ElasticsearchClientSettings class. This is how I ended up doing it (this is the code from the Startup class that initializes the elasticsearch client):
var uri = new Uri("my-deployment-uri");
var settings = new ElasticsearchClientSettings(uri)
.Authentication(new ElasticsearchApiKey("my-api-key"))
.EnableDebugMode();
if (settings is ElasticsearchClientSettingsBase<ElasticsearchClientSettings> settingsBase)
{
settings = settingsBase.DefaultFieldNameInferrer(fieldName => fieldName);
}
return new ElasticsearchClient(settings);