elasticsearch,nest,C#,elasticsearch,Nest" /> elasticsearch,nest,C#,elasticsearch,Nest" />

C# 如何在Elasticsearch 5.6中将枚举保存为字符串而不使用属性映射(使用嵌套)

C# 如何在Elasticsearch 5.6中将枚举保存为字符串而不使用属性映射(使用嵌套),c#,elasticsearch,nest,C#,elasticsearch,Nest,我想在Elasticsearch索引中以字符串的形式存储所有枚举。因为我使用的模型需要独立于任何特定技术,所以我不能使用 我知道您可以在创建连接设置时传递SerializerFactory,但我不知道什么选项将更改枚举的序列化 下面是我用来连接NEST的代码: var serializers = new SerializerFactory(<what to put here?>); var settings = new ConnectionSettings(myUri, serial

我想在Elasticsearch索引中以字符串的形式存储所有枚举。因为我使用的模型需要独立于任何特定技术,所以我不能使用

我知道您可以在创建
连接设置时传递
SerializerFactory
,但我不知道什么选项将更改枚举的序列化

下面是我用来连接NEST的代码:

var serializers = new SerializerFactory(<what to put here?>);
var settings = new ConnectionSettings(myUri, serializers)
    .DefaultIndex(myIndex)
    .InferMappingFor<MyModel>(m => m
        .IdProperty(s => s.MyId)
    );
var client = new ElasticClient(settings);

嵌套版本:
5.5.0
(最新版本)

多亏了@RussCam,我才能找到解决方案。以下是我现在使用的代码:

var connectionPool = new SingleNodeConnectionPool(new Uri(myUri));
var connection = new HttpConnection();
var serializers = new SerializerFactory((s, v) => s.Converters.Add(new StringEnumConverter()) );

var settings = new ConnectionSettings(connectionPool, connection, serializers)
    .DefaultIndex(StatusIndex)
    .InferMappingFor<MyModel>(m => m
        .IdProperty(s => s.MyId)
    );

var client = new ElasticClient(settings);
var connectionPool=newsinglenodeconnectionpool(newuri(myUri));
var connection=新的HttpConnection();
var serializers=new SerializerFactory((s,v)=>s.Converters.Add(new StringEnumConverter());
var设置=新连接设置(连接池、连接、序列化程序)
.DefaultIndex(状态索引)
.InferMappingFor(m=>m
.IdProperty(s=>s.MyId)
);
var客户端=新的ElasticClient(设置);

第三行是重要的一行。添加到
SerializerFactory
Converters
中的
StringEnumConverter
将使每个枚举序列化为字符串并从字符串反序列化(使用此
ElasticClient
)。

我使用了@Leifb建议的类似方法(在属性上使用StringEnumConverter):

但是,如果对类型使用自动映射,则会出现问题,因此我为该类型创建了一个通用枚举来字符串属性访问者:

var result = await _client.PutIndexTemplateAsync(
    p.TemplateName, s=>s
        .Template(p.Template)
        .Mappings(m=>m
            .Map(p.TemplateName, mm=>mm
                .AutoMap<MyType>(new EnumAsStringPropertyVisitor())
            )
        ));


public class EnumAsStringPropertyVisitor : NoopPropertyVisitor
{
    public override void Visit(
        INumberProperty type,
        PropertyInfo propertyInfo,
        ElasticsearchPropertyAttributeBase attribute) 
    {
        if(propertyInfo.PropertyType.IsEnum)
        { 
            type.Type = "keyword"; 
        }
    }
}
var result=await\u client.PutIndexTemplateAsync(
p、 TemplateName,s=>s
.模板(p.Template)
.Mappings(m=>m
.Map(p.TemplateName,mm=>mm
.AutoMap(新的EnumAsStringPropertyVisitor())
)
));
公共类EnumAsStringPropertyVisitor:NoopPropertyVisitor
{
公众参观(
INumberProperty类型,
PropertyInfo PropertyInfo,
ElasticsearchPropertyAttributeBase属性)
{
if(propertyInfo.PropertyType.IsEnum)
{ 
type.type=“关键字”;
}
}
}

看看:。从
JsonNetSerializer
派生,您可以为
enum
的任何类型添加
StringEnumConverter
:这使用的是旧版本的客户端,但是
Func
委托可能是您想要添加到派生序列化程序上的
ContractConverters
的内容:@RussCam谢谢,你的第一句话帮了大忙!
[JsonConverter(typeof(StringEnumConverter))] 
public MyEnum Status {get;set;}
var result = await _client.PutIndexTemplateAsync(
    p.TemplateName, s=>s
        .Template(p.Template)
        .Mappings(m=>m
            .Map(p.TemplateName, mm=>mm
                .AutoMap<MyType>(new EnumAsStringPropertyVisitor())
            )
        ));


public class EnumAsStringPropertyVisitor : NoopPropertyVisitor
{
    public override void Visit(
        INumberProperty type,
        PropertyInfo propertyInfo,
        ElasticsearchPropertyAttributeBase attribute) 
    {
        if(propertyInfo.PropertyType.IsEnum)
        { 
            type.Type = "keyword"; 
        }
    }
}