GUID ID为但没有属性的弹性搜索

本文关键字:搜索 属性 ID GUID | 更新日期: 2023-09-27 18:00:05

我们希望从关系数据库切换到弹性搜索,我正在尝试使用Nest启动并运行一些基本代码。我们现有的对象使用id的guid,我想将其保存到弹性搜索索引中。

我不想添加任何特定的属性,因为类在不同的应用程序中使用,我也不想向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);

测试类型为:

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

然而,我得到了一个错误,如:

服务器错误:400类型:mapper_parsing_exception原因:"未能parse[id]"CausedBy:"类型:number_format_exception原因:"For输入字符串:"c9c0ed42-86cd-4a94-bc86-a6112f4c9188"

我想我需要指定一个映射来告诉服务器Id是一个字符串,但如果不使用属性,我找不到任何关于如何做到这一点的示例或文档。

GUID ID为但没有属性的弹性搜索

假设您使用的是Elasticsearch 2.x和NEST 2.x(例如,在撰写本文时,两者的最新版本分别为Elasticsearch 2.3.5和NEST 2.4.3),则NEST将默认情况下从Id属性自动推断POCO的id。在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; }
}

查看自动映射文档,了解如何显式映射用于控制规范、分析器、多字段等的POCO的更多示例。

我通常所做的是拥有一个仅特定于Elasticsearch的单独类。并使用Automapper将其映射到DTO或ViewModel中,或将Model映射到Elasticsearch文档中。

这样,您就不必公开一个在NEST中具有依赖关系的对象,以及可能只针对Elasticsearch的属性。

另一个很好的原因是,通常情况下,ES中的文档是扁平的,所以在将对象索引到ES之前,通常会将它们扁平化。