【问题标题】:Elasticsearch(C# nest): Map abstract propertyElasticsearch(C# nest):映射抽象属性
【发布时间】:2018-10-30 03:16:02
【问题描述】:

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

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

我收到此错误: 无法创建 ProductDiscount 类型的实例。类型是接口或抽象类,不能实例化。路径“discount.amount”,第 1 行,位置 1098。

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

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)));

【问题讨论】:

  • 您能展示一下您是如何读取数据的吗?需要指定要反序列化成什么类型​​,不能反序列化成抽象类
  • 嗨,Kenneth,我更新了问题。我的问题是我不知道在哪里定义如何反序列化 Discount 的东西。
  • 是的,问题是当您反序列化时,它不知道要创建什么实例。看看这里,看看你是否能找到解决方法:github.com/elastic/elasticsearch-net/issues/1155 注意:你可能需要重新索引你的数据

标签: c# elasticsearch nest


【解决方案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()
                }
            });
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-30
    • 1970-01-01
    • 2020-01-29
    • 2015-03-29
    • 2019-08-19
    相关资源
    最近更新 更多