I'm trying to add a field which takes the system's datetime (DateTime.Now) and index it on ES server.
When I insert it without any custom format, I can index the documents. But if I mention any format, it is throwing an error. can some one help me to correct ?
my mappings:
var createIndexResponse =
client.CreateIndex(defaultIndex, c => c
.Mappings(m => m
.Map<Document>(mp => mp
.Properties(ps => ps
.String(s => s.Name(e => e.Title))
.Date(dt=>dt.Name(en=>en.CreatedDate))
. //other fields
If I add something like this, .Date(dt=>dt.Name(en=>en.CreatedDate).Format("yyyy-MM-dd HH:mm:ss))" then it is throwing an error.
Hey @ASN, what version of NEST are you using and what version of Elasticsearch are you targeting?
By default, DateTime, DateTime?, DateTimeOffset and DateTimeOffset? are serialized using ISO 8601 format using the IsoDateTimeConverter in the Json.NET library. If you specify a different format to use in the mapping, then you will also need to change the serialization for the DateTime property to ensure that values get serialized according to the specified format; the format specified on the mapping only tells Elasticsearch about the format, the serializer used by the client also needs to be told.
You can specify the format to use when serializing DateTime by deriving from JsonNetSerializer and setting it as the serializer to use on ConnectionSettings. For example, you can add your own JsonConverter for handling DateTime
public class MyJsonNetSerializer : JsonNetSerializer
{
public MyJsonNetSerializer(IConnectionSettingsValues settings) : base(settings) { }
protected override IList<Func<Type, JsonConverter>> ContractConverters => new List<Func<Type, JsonConverter>>
{
t => {
if (t == typeof(DateTime) ||
t == typeof(DateTime?) ||
t == typeof(DateTimeOffset) ||
t == typeof(DateTimeOffset?))
{
return new Newtonsoft.Json.Converters.IsoDateTimeConverter
{
DateTimeFormat = "yyyy-MM-dd HH:mm:ss"
};
}
return null;
}
};
}
and
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var connectionSettings = new ConnectionSettings(pool, settings => new MyJsonNetSerializer(settings));
IF you don't want to change the serialized format of allDateTime, then you can attribute the CreatedDate property on the Document class with your own JsonConverter type that specifies the format to use
public class MyDateTimeConverter : IsoDateTimeConverter
{
public MyDateTimeConverter()
{
DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
}
}
public class Document
{
public int Id { get; set; }
public string Title { get; set;}
[JsonConverter(typeof(MyDateTimeConverter))]
public DateTime CreatedDate { get; set;}
}
To answer your second question, you can also sort on this field to return the five most recently created documents
client.Search<Document>(s => s
.Size(5)
.Sort(so => so
.Descending(d => d.CreatedDate)
)
)
);
What's the error? Can you include the .DebugInformation from the response? If you need more details to debug, you can also set .DisableDirectStreaming() on ConnectionSettings, which will also provide the request and response.
when it comes to this statement then it is throwing error.
var response = client.IndexMany(list, ConfigurationManager.AppSettings["index"]);
if (!response.IsValid)
{
foreach (var item in response.ItemsWithErrors)
Console.WriteLine("Failed to index document {0}: {1}", item.Id, item.Error);
Console.WriteLine(response.CallDetails.OriginalException.Message);
}
The date format is not reflected in the mapping. If you're trying to update an existing mapping, your best bet is to create a new index with the new mapping and re-index your data into it. Looking at your C# mapping call
You also need to specifiy .Format(format) on .Date() i.e
var createIndexResponse =
client.CreateIndex(defaultIndex, c => c
.Mappings(m => m
.Map<Document>(mp => mp
.Properties(ps => ps
.String(s => s.Name(e => e.Title))
.Date(dt=> dt.Name(en=>en.CreatedDate).Format("yyyy-MM-dd HH:mm:ss"))
. //other fields
Based on this, I think the issue must be somewhere in your code. If ConfigurationManager.AppSettings["syncMode"] is not Full for example, your code won't delete the existing index.
I changed everything except this statement. var connectionSettings = new ConnectionSettings(pool, settings => new MyJsonNetSerializer(settings))
Sorry for my mistake. Because of it you had to write a working code. Sorry again.
And Thanks a ton Russ..
But how is this different from the other approach you have mentioned? (like the below one)
Even in this approach should I add the statement which I missed like the above one?
IF you don't want to change the serialized format of all DateTime, then you can attribute the CreatedDate property on the Document class with your own JsonConverter type that specifies the format to use
public class MyDateTimeConverter : IsoDateTimeConverter
{
public MyDateTimeConverter()
{
DateTimeFormat = "yyyy-MM-dd HH:mm:ss";
}
}
public class Document
{
public int Id { get; set; }
public string Title { get; set;}
[JsonConverter(typeof(MyDateTimeConverter))]
public DateTime CreatedDate { get; set;}
}
changing the date format on settings using a derived serializer like MyJsonNetSerializer will apply the serialization format to all DateTime - you may not want to do this, in which case, applying a custom converter on the type property will apply the serialization format only to that property.
If you're using a custom converter in an attribute applied to a property, you don't need to provide your own derived json serializer to settings. This is all Json.NET specific, so it's worth having a look at its documentation
Apache, Apache Lucene, Apache Hadoop, Hadoop, HDFS and the yellow elephant
logo are trademarks of the
Apache Software Foundation
in the United States and/or other countries.