使用没有属性的GUID ID进行弹性搜索

时间:2016-08-03 13:04:42

标签: c# nest elasticsearch-net

我们正在寻求从关系数据库切换到弹性搜索,我正在尝试使用Nest获得一些基本代码并运行。我们有现有的对象使用guid来保存我想保存到弹性搜索索引中的ID。

我不想添加任何特定属性,因为该类在不同的应用程序中使用,我不想在Nest中添加不必要的依赖项。

现在我的代码看起来像这样:

var node = new Uri("http://localhost:9200");
var settings = new ConnectionSettings(node) 
settings.DefaultIndex = "test";
var client = new ElasticClient(settings);

var testItem = new TestType { Id = Guid.NewGuid(), Name = "Test", Value = "10" };

var response = client.Index(testItem);

使用TestType:

public class TestType
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public decimal Value { get; set; }
}

但是我收到的错误如下:

  

ServerError:400Type:mapper_parsing_exception原因:“失败了   parse [id]“CausedBy:”输入:number_format_exception原因:“For   输入字符串:“c9c0ed42-86cd-4a94-bc86-a6112f4c9188”“

我想我需要指定一个映射来告诉服务器Id是一个字符串,但是我找不到任何关于如何在不使用属性的情况下执行此操作的示例或文档。

2 个答案:

答案 0 :(得分:1)

假设您正在使用Elasticsearch 2.x和NEST 2.x(例如,在编写本文时最新的两个是Elasticsearch 2.3.5和NEST 2.4.3),那么NEST will automatically infer the id of a POCO by default from the Id property。对于GUID id,它将在Elasticsearch中保存为字符串。

这是一个让你前进的例子

void Main()
{
    var node = new Uri("http://localhost:9200");
    var settings = new ConnectionSettings(node)
        // default index to use if one is not specified on the request
        // or is not set up to be inferred from the POCO type
        .DefaultIndex("tests");

    var client = new ElasticClient(settings);

    // create the index, and explicitly provide a mapping for TestType
    client.CreateIndex("tests", c => c
        .Mappings(m => m
            .Map<TestType>(t => t
                .AutoMap()
                .Properties(p => p
                    // don't analyze ids when indexing,
                    // so they are indexed verbatim
                    .String(s => s
                        .Name(n => n.Id)
                        .NotAnalyzed()
                    )
                )
            )
        )
    );

    var testItem = new TestType { Id = Guid.NewGuid(), Name = "Test", Value = "10" };

    // now index our TestType instance
    var response = client.Index(testItem);
}

public class TestType
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public decimal Value { get; set; }
}

Take a look at the Automapping documentation for more examples如何明确地映射POCO以控制normsanalyzersmulti_fields

答案 1 :(得分:0)

我通常做的是拥有一个仅针对Elasticsearch的单独类。并使用Automapper将其映射到DTO或ViewModel,或将模型映射到Elasticsearch文档。

这样,您就不必公开在NEST中具有依赖关系的对象以及可能仅特定于Elasticsearch的属性。

另一个很好的理由是,通常情况下,ES中的文档是平的,因此在将对象编入ES之前,通常会将对象展平。