具有不带属性的 GUID ID 的弹性搜索

Elastic search with GUID ID without attributes

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

我不想添加任何特定属性,因为 class 用于不同的应用程序,我不想向 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; }
}

但是我收到如下错误:

ServerError: 400Type: mapper_parsing_exception Reason: "failed to parse [id]" CausedBy: "Type: number_format_exception Reason: "For input string: "c9c0ed42-86cd-4a94-bc86-a6112f4c9188""

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

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

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

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

假设您正在使用 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 of how to explicitly map a POCO for controlling norms, analyzers, multi_fields