【问题标题】:Elastic search with GUID ID without attributes具有 GUID ID 且不带属性的弹性搜索
【发布时间】:2016-08-17 12:56:30
【问题描述】:

我们正在寻求从关系数据库切换到弹性搜索,我正在尝试使用 Nest 启动和运行一些基本代码。我们有现有的对象,这些对象使用 ids 的 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);

TestType 为:

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

但是我收到如下错误:

ServerError: 400Type: mapper_parsing_exception 原因:“失败 解析 [id]" CausedBy: "类型:number_format_exception 原因:"对于 输入字符串:"c9c0ed42-86cd-4a94-bc86-a6112f4c9188""

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

【问题讨论】:

    标签: c# nest elasticsearch-net


    【解决方案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

    【讨论】:

    • 解决了,谢谢。我找到了该文档,但我认为它不是很好,可能可以作为参考,但对于刚开始使用 API 的人来说根本不容易遵循。
    • @Mant101 随时在此处或discuss.elastic.co/c/elasticsearch 提问。对文档的拉取请求也很受欢迎;)
    【解决方案2】:

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

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

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

    【讨论】:

    • 这些类型已经是扁平的,因为它们保存在关系数据库中,这是它们的主要功能。它们还用于网站中不值得拥有视图模型的地方。还有很多,我不想全部复制。
    • 明白了,从错误信息看来。 NEST 能够推断出 id 字段,但无法推断出 Guid 类型。
    猜你喜欢
    • 2016-03-28
    • 2018-05-12
    • 2012-02-12
    • 1970-01-01
    • 2020-11-03
    • 1970-01-01
    • 2015-04-27
    • 2019-11-09
    • 1970-01-01
    相关资源
    最近更新 更多