如何在NEST中索引和搜索接口类型的嵌套属性

时间:2014-10-14 21:32:22

标签: elasticsearch nest

我有一个以下文档索引实体:

[ElasticType(Name = "Document", IdProperty = "Id")]
public class Document
{
    [ElasticProperty(Index = FieldIndexOption.NotAnalyzed)]
    public string Id { get; set; }

    [ElasticProperty(Type = FieldType.Nested)]
    public ICustomer Customer { get; set; } 
}

其中ICustomer可以是不同类型:

public interface ICustomer
{
}

public class Supplier : ICustomer
{   
    public string Name { get; set; }    

    //another properties
}

public class Vendor : ICustomer
{   
    public string Name { get; set; }    

    //another properties
}

我的映射是:

Client.CreateIndex("Document", c => c
                .AddMapping<Document>(m => m
                .SearchAnalyzer("standard")
                .IndexAnalyzer("standard")
                .MapFromAttributes()
                .NumericDetection()
                .DateDetection();

当我将文档保存到索引时,它还保存了正确序列化的嵌套对象(供应商或供应商)。

但我在搜索数据时遇到问题。我正在从newtonsoft获得以下异常:

Type is an interface or abstract class and cannot be instantiated.

我正在尝试创建自定义json转换器

public class CustomJsonConvertor : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        serializer.Serialize(writer, value);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {            
        if (objectType == typeof(Supplier))
        {
            return serializer.Deserialize(reader, typeof (Supplier));
        }

        if (objectType == typeof(Vendor))
        {
            return serializer.Deserialize(reader, typeof(Vendor));
        }

        throw new NotSupportedException(string.Format("Type {0} unexpected.", objectType));
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof (Supplier) || objectType == typeof (Vendor);
    }
}

并将其注册为:

settings.AddContractJsonConverters(t => typeof(ICustomer).IsAssignableFrom(t) ? new CustomJsonConvertor() : null);

但是我在ReadJson方法中收到异常,因为objectType的类型为ICustomer,而条件if(objectType == typeof(Supplier))永远不会成立。在这个方法中参数existingValue为null,所以我没有选项如何确定 正确的类型。

注意:我的实体(供应商,供应商)是分开的dll(插件),在定义Document时我没有直接访问它们。

你能告诉我我做错了什么,或者给我一些最佳实践建议如何处理文档索引中的接口或抽象类以及如何处理多态?

非常感谢!

1 个答案:

答案 0 :(得分:0)

该信息丢失,您需要检查JSON以提供差异化​​。

对于命中本身,NEST可以使用_type作为区别。对于文档中的集合,您必须编写jsonconverter以基于属性实例化正确的类型,或者指示Json.NET在自动序列化时为您编写该信息。