如何在ElasticSearch.NET中覆盖属性的类型和数据

时间:2016-12-11 18:40:24

标签: elasticsearch nest

我有一个这样的对象:

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部分,然后对其进行查询以执行相同操作。

由于依赖性,我无法更改对象(如果我必须更改依赖项,但我会尝试避免这种情况)。

有没有办法实现这一目标,还是一厢情愿?

1 个答案:

答案 0 :(得分: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);
}