elasticsearch-net
elasticsearch-net copied to clipboard
AutoMap and DynamicTemplates (copyto) not working as expected
NEST/Elasticsearch.Net version: 7.10
Elasticsearch version: 7.10
Description of the problem including expected versus actual behavior:
Fluent Mapping with Dynamic Template issue. Auto Map with a Dynamic Template to copy all string fields to another field doesnt not work correctly, there is no error when creating the index but the copy_to is missing from each of the field mappings.
If I remove the automap then the copy_to shows in the field mapping. I would expect the AutoMap to create the fields (and nested fields) as it currently does but also add the copy_to when the field is classed as a string.
Steps to reproduce:
Create a new index with Map set like this:
.Map<myType>( x => x .AutoMap<myType>() .DynamicTemplates(d => d .DynamicTemplate("searchFields", dd => dd .MatchMappingType("string").Mapping(mp => mp .Text(t => t .CopyTo(ct => ct .Field(f => f.Search))))) )
Note that the copy_to is missing from field mappings. Remove AutoMap and note that the copy_two is present in the field mappings.
Expected behavior AutoMap and DynamicTemplates to work together?
I was hoping it would end up looking like this:
"state": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } }, "copy_to": [ "search" ] },
Thanks,
Hi @whittssg. I can see how this may be confusing.
AutoMap is a client-side helper which infers mappings within the client from your .NET types. When used, we're able to provide a best guess explicit mapping on index creation against those types. When you use this, you're buying into the defaults we infer, which you can later customise.
Dynamic templates are a server-side feature intended to provide mapping rules beyond the defaults applied to fields that do not have an explicit mapping. Dynamic templates won't get applied to the inferred mapping that the client creates for your properties using AutoMap
.
There are a couple of options here:
1 - Don't use AutoMap
at all, but provide explicit mappings for all properties that won't get handled by any dynamic templates you define. Where you don't specify an explicit mapping it will be handled by the server behaviour and any matching templates.
2 - Use AutoMap
as a starting point but provide additional overrides where required.
client.Indices.Create("my-index",
c => c.Map<MyType>(m =>
m.AutoMap<MyType>().Properties(p =>
p.Text(t => t.Name(n => n.State).CopyTo(ct => ct.Field("search"))))));
Hi @stevejgordon, thanks for explaining, its appreciated. Option 2 was what i was using:
.Text(t => t.Name(n => n.Reason).CopyTo(ct => ct.Field("search")) .Fields(ff=>ff .Keyword(k=>k.Name("keyword").IgnoreAbove(256))))
It seems to work well so I will continue to use that.
Has the team considered having an option that creates the fields from automap (as it does now with the Keyword as a multi-field) but with an option to simulate the _all field from the older versions? Something like this: .AutoMap(am=>am.CopyAllFieldsTo(ct => ct.Field("search")))
Thanks again.
You're welcome @whittssg. I'm not sure if it's been raised in the past but I can see some value there. I've collected this on a set of suggestions I'm compiling and will evaluate it further. I'll keep this open for now to track it and allow people to upvote (thumbs up) if they would benefit from this.
Thank you very much @stevejgordon