2016-12-11 28 views
0

我有一個這樣的對象:我如何可以覆蓋屬性的類型和datat在ElasticSearch.NET

public class MyDate { 
    public DateTime Original { get; set; } 
    public string MungedFormatForAnotherSystem { get; set; } 
} 

public class ESClass { 
    public string Id { get;set; } 
    public MyDate LastUpdatedDate {get;set;} 
} 

我使用NEST客戶端這樣的:

var client = new ElasticClient(); 
client.Index(doc, i => i.Index("myindex"); 

我想要的是將MyDate序列化爲ES,只需要Original部分,然後對其進行查詢即可。

由於依賴關係,我無法更改對象(如果必須更改依賴關係,我會嘗試避免這種情況)。

有沒有辦法做到這一點,或者是一廂情願?

+0

所以,'MungedFormatForAnotherSystem'不應被序列化,並存儲在Elasticsearch以任何方式做到這一點? –

+0

正確,它需要以相同的名稱存儲,但是作爲日期而不是嵌套對象。 – Martin

回答

0

您可以用自定義Json.Net JsonConverter

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<ESClass>(mm => mm 
       .AutoMap() 
       .Properties(p => p 
        // map the type as a "date" field type 
        .Date(t => t 
         .Name(n => n.LastUpdatedDate) 
        ) 
       ) 
      ) 
     ) 
    ); 

    client.IndexMany(new[] { 
     new ESClass { Id = "1", LastUpdatedDate = new MyDate { Original = DateTime.UtcNow.Date } }, 
     new ESClass { Id = "2", LastUpdatedDate = new MyDate() }, 
     new ESClass { Id = "3" } 
    }); 

    client.Refresh(defaultIndex); 

    // returns document with Id "1" 
    client.Search<ESClass>(s => s 
     .Query(q => +q 
      .Term(f => f.LastUpdatedDate, DateTime.UtcNow.Date) 
     ) 
    ); 
} 

public class ESClass 
{ 
    public string Id { get; set; } 
    public MyDate LastUpdatedDate { get; set; } 
} 

[JsonConverter(typeof(MyDateConverter))] 
public class MyDate 
{ 
    public DateTime Original { get; set; } 
    public string MungedFormatForAnotherSystem { get; set; } 
} 

public class MyDateConverter : JsonConverter 
{ 
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     var v = (MyDate)value; 
     writer.WriteValue(v.Original); 
    } 

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     switch (reader.TokenType) 
     { 
      case JsonToken.Date: 
       return new MyDate { Original = (DateTime)reader.Value }; 
      default: 
       throw new JsonSerializationException($"Cannot deserialize {reader.TokenType} to {typeof(MyDate).FullName}"); 
     } 
    } 

    public override bool CanConvert(Type objectType) => typeof(MyDate).IsAssignableFrom(objectType); 
} 
+0

哇,非常徹底。有沒有辦法做到這一點,而不添加屬性?如何直接將其應用於客戶? – Martin

+0

是的,您可以將「MyDate」類型的Converter添加到序列化程序中。從'JsonNetSerializer'派生,覆蓋'ContractConverters'並返回轉換器的一個實例,如果類型匹配的話。請參閱http://stackoverflow.com/a/372​​04337/1831 –