NEST/Elasticsearch.Net version 5.0.0-rc4:
Elasticsearch version 5.0.0:
We are having an issue while mapping a array of strings. These strings should be keywords but endup being text fields.
So basically:
.Mapping(dm => dm.Keyword(k => k.Name(n => n.ArrayOfTerms)))
Generates this
"arrayOfTerms": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
Instead of
"arrayOfTerms": {
"type": "keyword",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
We are using a json payload with the mapping instead of NEST's fluent interface, which solves the issue, but we would like to know if this is a bug or if we are doing something wrong.
.Mapping(dm => dm.Keyword(k => k.Name(n => n.ArrayOfTerms)))
This doesn't look quite right; the mapping for a field should be inside of .Properties() to take effect. Also, the expected mapping does not match the keyword mapping you have, as the mapping is not a multi_field, but the expected mapping is.
Here's an example of automapping. With .AutoMap(), NEST will infer the POCO string property as a text field type mapping, with a keyword sub-field (akin to the mapping that Elasticsearch would infer with dynamic mapping)
```c#
void Main()
{
var pool = new SingleNodeConnectionPool(new Uri($"http://localhost:9200"));
var defaultIndex = "default-index";
var connectionSettings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex);
var client = new ElasticClient(connectionSettings);
client.CreateIndex(defaultIndex, c => c
.Mappings(m => m
.Map<Document>(mm => mm
.AutoMap()
)
)
);
}
public class Document
{
public string[] Property { get; set; }
}
this produces the mapping
```json
{
"mappings": {
"document": {
"properties": {
"property": {
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
}
}
}
}
}
Often, it can be useful to combine automapping with some overrides i.e. let automap automatically map as much as it can and then override the mappings that you want to explicitly change from what will be inferred. Here's what that looks like
```c#
client.CreateIndex(defaultIndex, c => c
.Mappings(m => m
.Map
.AutoMap()
.Properties(p => p
.Keyword(k => k
.Name(n => n.Property)
)
)
)
)
);
which produces the mapping
```json
{
"mappings": {
"document": {
"properties": {
"property": {
"type": "keyword"
}
}
}
}
}
Yeah, that did the trick.
Thanks.
Most helpful comment
This doesn't look quite right; the mapping for a field should be inside of
.Properties()to take effect. Also, the expected mapping does not match the keyword mapping you have, as the mapping is not amulti_field, but the expected mapping is.Here's an example of automapping. With
.AutoMap(), NEST will infer the POCO string property as atextfield type mapping, with akeywordsub-field (akin to the mapping that Elasticsearch would infer with dynamic mapping)```c#
void Main()
{
var pool = new SingleNodeConnectionPool(new Uri($"http://localhost:9200"));
var defaultIndex = "default-index";
var connectionSettings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex);
}
public class Document
{
public string[] Property { get; set; }
}
Often, it can be useful to combine automapping with some overrides i.e. let automap automatically map as much as it can and then override the mappings that you want to explicitly change from what will be inferred. Here's what that looks like
```c#(mm => mm
client.CreateIndex(defaultIndex, c => c
.Mappings(m => m
.Map
.AutoMap()
.Properties(p => p
.Keyword(k => k
.Name(n => n.Property)
)
)
)
)
);