Kenneth
Kenneth

Reputation: 28737

NEST 5.5 Attribute mapping and custom JsonConverter not working

We're using Nest 5.5.0 and attribute mapping to create our indices in Elasticsearch. As part of some of our attributes, we're using custom JsonConverters.

We're migrating from 1.7.3, where this mapping was handled correctly. After upgrading, we can see in the mapping that it has mapped the field without using the converter. When we then index a document, the converter is used and the index operation fails.

Example:

Nest and Elasticsearch 1.7.3

// code
public class MyItem
{
    [JsonProperty("start")]
    [JsonConverter(typeof(LocalTimeConverter))]
    public LocalTime Start { get; set; }
}

// index creation
elasticClient.CreateIndex("indexname", d => d.AddMapping<MyItem>(m => m.MapFromAttributes()))

// generated mapping (mapped as how the JsonConverter would output it)
"myitem": {
    "start": {
        "type": "string"
    }
}

Nest and Elasticsearch 5.5.0

// code
public class MyItem
{
    [JsonProperty("start")]
    [JsonConverter(typeof(LocalTimeConverter))]
    public LocalTime Start { get; set; }
}

// index creation
elasticClient.CreateIndexAsync(IndexName<T>(), d => d.Mappings(m => m.Map<MyItem>(mm => mm.AutoMap())));

// generated mapping (essentially a serialized version of the class)
"myitem": {
     "properties": {
        "clockHourOfHalfDay": { "type": "integer"},
        ...
        ...
        "hour": {"type": "integer" }
}

NOTES:

  • LocalTime is a class from the NodaTime library
  • The custom LocalTimeConverter takes the LocalTime and outputs a string

How can I force Nest 5.5.0 to take into account the JsonConverter-attribute when generating my mappings?

Upvotes: 1

Views: 657

Answers (1)

Russ Cam
Russ Cam

Reputation: 125498

To map LocalTime as a keyword type (which I think is what you want, which will not be analyzed, but still be indexed and searchable), you can use

public class MyItem
{
    [JsonProperty("start")]
    [JsonConverter(typeof(LocalTimeConverter))]
    [Keyword]
    public LocalTime Start { get; set; }
}

And create the index and mapping as you are currently doing.

You could omit the JsonPropertyAttribute too if you wanted as NEST camel cases property names by default.

This produces the mapping

{
  "mappings": {
    "myitem": {
      "properties": {
        "start": {
          "type": "keyword"
        }
      }
    }
  }
}

Upvotes: 2

Related Questions