Elasticsearch(C#nest):地图抽象属性

时间:2018-10-29 15:51:39

标签: c# elasticsearch nest

我在C#中有一个ProductDiscount类。其他类继承自它(FlatDiscount,PercentageDiscount等)。

在Elastic中存储数据似乎可行,但我无法从Elastic中读取数据。

我收到此错误: 无法创建类型为ProductDiscount的实例。类型是接口或抽象类,无法实例化。路径“折扣金额”,第1行,位置1098。

当我查看索引时,折扣确实是集合中的storef,但是没有指示类的类型。

是否可以使用巢式客户端在c#中映射抽象属性?

我尝试使用此映射描述符,但没有成功:

mappingsDescriptor.Map<Product>(x => x
                .Properties(props => props

                    .Object<ProductDiscount>(o => o.Name(prop => prop.Discount))
                    .Object<FlatProductDiscount>(o => o.Name(prop => prop.Discount).AutoMap())
                    .Object<PercentageProductDiscount>(o => o.Name(prop => prop.Discount).AutoMap())
                    .Object<FreeProductProductDiscount>(o => o.Name(prop => prop.Discount).AutoMap())
                    .Object<QuantityProductDiscount>(o => o.Name(prop => prop.Discount).AutoMap())
                 )
            );

使用ElasticClient进行读取:

    var result = await ElasticClient.SearchAsync<Product>(new SearchRequest(Indices.Index(index: CollectionName)));

1 个答案:

答案 0 :(得分:1)

我找到了解决方法!

我使用JsonSubTypes package编写了一个自定义转换器。

    private static JsonConverter DiscountConverter()
    {
        var assembly = Assembly.GetAssembly(typeof(ProductDiscount));

        var builder = JsonSubtypesConverterBuilder
            .Of(typeof(ProductDiscount), "Type");

        assembly
            .GetTypes()
            .Where(type => type.IsSubclassOf(typeof(ProductDiscount)) && !type.IsAbstract)
            .ForEach(s =>
            {
                builder.RegisterSubtype(s, s.Name);
            });

        var converter = builder
            .SerializeDiscriminatorProperty()
            .Build();

        return converter;
    } 

我的连接是这样建立的

            var pool = new SingleNodeConnectionPool(new Uri(uris.First()));
            connectionSettings = new ConnectionSettings(pool, connection, SourceSerializer());

    private static ConnectionSettings.SourceSerializerFactory SourceSerializer()
    {
        return (builtin, settings) => new JsonNetSerializer(builtin, settings,
            () => new JsonSerializerSettings
            {
                Converters = new List<JsonConverter>
                {
                    new StringEnumConverter(),
                    DiscountConverter()
                }
            });
    }