1

Here is my question. Due to project needs, we have to keep our dates within elasticsearch index in the same format. What we've tried is the next way -

            var connectionPool = new SniffingConnectionPool(nodeList);
            var connectionSettings = new ConnectionSettings(connectionPool)
                 .SetJsonSerializerSettingsModifier(
                  m => m.DateFormatString = "yyyy-MM-ddTHH:mm:ss.fffffffK")
            // other configuration goes here

But it didn't work out. Searching through ES index, I saw dates with dropped trailing zeros ( like 2015-05-05T18:55:27Z insted of expected 2015-05-05T18:55:27.0000000Z). Neither did next option help:

            var connectionPool = new SniffingConnectionPool(nodeList);
            var connectionSettings = new ConnectionSettings(connectionPool)
                 .SetJsonSerializerSettingsModifier(m =>
                    {
                        m.Converters.Add(new IsoDateTimeConverter { DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss.fffffffK"});
                    })
            // other configuration goes here

With digging into ElasticClient at run-time, I've found that eventually there is a contract resolver which seems like overrides all those settings:

          public class ElasticContractResolver : DefaultContractResolver
          {
              protected override JsonContract CreateContract(Type objectType)
              {
                  JsonContract contract = base.CreateContract(objectType);
                  ...
                  if (objectType == typeof(DateTime) || objectType == typeof(DateTime?))
                      contract.Converter = new IsoDateTimeConverter();
                  ...
                  if (this.ConnectionSettings.ContractConverters.HasAny())
                  {
                      foreach (var c in this.ConnectionSettings.ContractConverters)
                      {
                          var converter = c(objectType);
                          if (converter == null)
                              continue;
                          contract.Converter = converter;
                          break;
                      }
                  }

                 return contract;
             }
          }

So if I have it right, without specifying a converter explicitly(via Connection Settings.AddContractJsonConverters()), my json settings will be gone since IsoDateTimeConverter is instantiated with the default settings rather than ones I've passed through SetJsonSerializerSettingsModifier.

Has anyone run into this issue? Or I'm just missing something? Thanks in advance!

Kiryl
  • 1,416
  • 9
  • 21

1 Answers1

0

This is how I handled custom date format for my needs:

public class Document
{
    [ElasticProperty(DateFormat = "yyyy-MM-dd", Type = FieldType.Date)]
    public string CreatedDate { get; set; }
}

client.Index(new Document {CreatedDate = DateTime.Now.ToString("yyyy-MM-dd")});

My document in ES

{
    "_index": "indexname",
    "_type": "document",
    "_id": "AU04kd4jnBKFIw7rP3gX",
    "_score": 1,
    "_source": {
       "createdDate": "2015-05-09"
    }
}

Hope it will help you.

Rob
  • 9,664
  • 3
  • 41
  • 43
  • Thanks Rob! It seems to be a way out. Also I've found out that using `ConnectionSettings.AddContractJsonConverters` solves the problem. But it's still confusing why `ConnectionSettings.SetJsonSerializerSettingsModifier` doesn't work properly. – Kiryl May 10 '15 at 15:50
  • It's worth to report this issue here https://github.com/elastic/elasticsearch-net – Rob May 10 '15 at 16:22
  • Agree. Just was curious if it's my fault like I simply forgot something to set up. – Kiryl May 10 '15 at 20:01