Elasticsearch(C# nest):地图摘要属性
Elasticsearch(C# nest): Map abstract property
我在 C# 中有一个 class ProductDiscount。其他 class 继承自它(FlatDiscount、PercentageDiscount 等)。
在 Elastic 中存储数据似乎可行,但我无法从 Elastic 读取数据。
我收到此错误:
无法创建 ProductDiscount 类型的实例。类型是一个接口或抽象 class 并且不能被实例化。路径 'discount.amount',第 1 行,位置 1098。
当我查看我的索引时,折扣确实是集合中的 storef,但没有指示 class 的类型。
是否可以使用 nest 客户端在 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)));
我找到了解决办法!!
我使用 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()
}
});
}
我在 C# 中有一个 class ProductDiscount。其他 class 继承自它(FlatDiscount、PercentageDiscount 等)。
在 Elastic 中存储数据似乎可行,但我无法从 Elastic 读取数据。
我收到此错误: 无法创建 ProductDiscount 类型的实例。类型是一个接口或抽象 class 并且不能被实例化。路径 'discount.amount',第 1 行,位置 1098。
当我查看我的索引时,折扣确实是集合中的 storef,但没有指示 class 的类型。
是否可以使用 nest 客户端在 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)));
我找到了解决办法!!
我使用 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()
}
});
}