【问题标题】:ElasticSearch NEST: Create an index through ElasticClient by specifying jsonElasticSearch NEST:通过ElasticClient创建索引,指定json
【发布时间】:2015-05-15 13:37:24
【问题描述】:

我们允许客户在创建索引时定义自定义分析器。我们更愿意在 json 中指定这一点,以便通过底层 ElasticSearch 文档提供最大的灵活性和可理解性。

我想使用在 json 字符串中定义的分析器、映射器等的任意描述来创建索引。使用感觉,我的命令是

PUT /my_index
{
    "settings": 
    {
        "analysis": 
        {
            "char_filter" : 
            {
                "my_mapping" : 
                {
                    "type" : "mapping",
                    "mappings" : [".=>,", "'=>,"]
                }
            },
            "analyzer": 
            {
                "my_analyzer": 
                {
                    "type":         "custom",
                    "tokenizer":    "standard",
                    "filter":       ["lowercase" ],
                    "char_filter" : ["my_mapping"]
                }
            }
         }
      }
   }
}

理想情况下,我的代码应该类似于

string json = RetrieveJson();
ElasticSearchClient client = InitializeClient();
client.CreateIndexUsingJson( json ); // this is the syntax I can't figure out

here 帖子试图通过实例化 IndexSettings 然后调用 Add("analysis", json) 来做到这一点,但 Add 不是我正在使用的 ElasticSearch 库版本上的函数。

我能想到的选项包括:

  1. 不知何故使用 ElasticClient.Raw.IndicesCreatePost 或类似的东西
  2. 通过 IndexSettingsConverter.ReadJson() 将 json 字符串反序列化为 IndexSettings 对象,然后通过 ElasticClient.CreateIndex(ICreateIndexRequest) 应用该对象

这两种机制的文档都非常少。

我绝对尽量避免使用 CreateIndex 的 lambda 函数版本,因为将用户的 json 转换为 lamdba 表达式会很痛苦,而只是立即将它们转换回 NEST 深处的 json。

非常感谢上述 #1 或 #2 的其他选项或具体示例,这是解决此问题的推荐方法。

【问题讨论】:

  • 您使用哪个版本的 NEST?
  • 我与@mcating 合作。我们使用 Nest 版本 1.1.2。

标签: c# elasticsearch nest


【解决方案1】:

最简单的解决方案是实现原始问题中的选项 #1。

public void CreateIndex(string indexName, string json)
{
    ElasticClient client = GetClient();
    var response = _client.Raw.IndicesCreatePost(indexName, json);
    if (!response.Success || response.HttpStatusCode != 200)
    {
        throw new ElasticsearchServerException(response.ServerError);
    }
}

在修改转换器、JsonReaders 和 JsonSerializers 之后,我发现 IndexSettingsConverter 似乎没有正确地将任意设置 json 反序列化为有效的 IndexSettings 对象。感觉到一个兔子洞,我接受了 Manolis 的建议,并想出了如何将任意 json 直接应用于 ElasticClient.IElasticsearchClient 以避免对安全性和连接细节进行逆向工程。

为了得出这个结论付出了很大的努力,如果不通过大量未记录的 NEST 代码,完全不可能。

【讨论】:

  • _client.Raw.IndiciesCreatePost 在 Elasticsearch 2.x 中缺失。现在是 _client.LowLevel.IndicesCreatePost
【解决方案2】:

如果您想做类似上面描述的事情,那么您可以简单地使用 HttpClient 并将创建索引的请求发送到您的弹性搜索服务器。在这种情况下,您可以在请求的内容中包含您的 JSON。

试试下面的:

public async void CreateIndex() {
            using (var httpClient = new HttpClient()) {
                using (var request = new HttpRequestMessage(HttpMethod.Put, new Uri("http://elastic_server_ip/your_index_name"))) {
                    var content = @"{ ""settings"" : { ""number_of_shards"" : 1 } }";
                    request.Content = new StringContent(content);
                    var response = await httpClient.SendAsync(request);
                }
            }
        }

这个特定的 sn-p 将使用一个分片、一个副本(默认)以及默认设置和映射创建指向指定端点的索引。使用您的 json 更改内容变量。

【讨论】:

  • 这在某些情况下是可行的,但我们的 ElasticSearch 实例是通过 SSL 和码头保护的。与其创建一个 HttpClient 然后对权限/连接细节进行反向工程,对我们来说更好的答案是使用那些已经嵌入到 ElasticClient 实例中的连接细节。感谢您的帮助!
  • @mcating 没有什么不安全或需要通过直接 HTTP 调用进行逆向工程的。这就是我们在所有系统(在 Nginx 之后)中所做的。重用我们现有的 ES 知识比学习一个库要容易得多。没有什么只能在“某些情况下”起作用。这就是所有插件和扩展的方式,这就是我们使用 curl 与 ES 交互的方式,也是您将通过 NEST 看到的内容。有关更多信息,请参阅我的内部文档netfxharmonics.com/2015/11/learningelasticps
  • @DavidBetz:我的担忧是概念性的。通过直接访问 HttpClient,您将自己暴露于可能会随着时间而改变的实现细节。通过坚持使用 ElasticClient,它在概念上封装了所有必需的连接细节,客户端对底层实现细节变得更有弹性。
  • @mcating HTTP 接口正是许多人的核心卖点(与 MongoDB 相比)。此外,这些是接口,而不是实现细节;这些是版本化的 Web API。你的接口不是 NEST,你的接口是 HTTP 端点告诉你的。这是 RESTful 架构 101。我希望看到 NEST 被弃用。你说的好像我们在谈论“内部”和“私人”成员。这些是我们应该鼓励人们使用的公共 API。说真的,你没看过文档吗?它们是关于 HTTP API 的——它们不是“内部”或“实现细节”。
  • @DavidBetz:我认为我的措辞不清楚。 “内部”和“逆向工程”指的是我们在 GetClient() 中配置、实现和封装的自定义身份验证方案,它返回一个完全可用的 ElasticClient。随着连接/配置/身份验证细节的发展,切换到 ElasticClient/HttpClient 的混合模型会使库使用者感到困惑并增加维护成本。我们决定使用 NEST,因此有强烈的动机让所有客户使用同一个库。在这一点上为我回答了这个问题。感谢您的宝贵时间!
【解决方案3】:

好的,在更新到 Elasticsearch NEST v6.0.2 后,我不得不修改我的代码,并想将其发布在这里以供其他人使用。更改包括将CreateResponse 作为函数类型传入,并在响应中使用ApiCall 属性。

public bool CreateIndex(string indexName, string json)
{
    var response = _client.LowLevel.IndicesCreate<CreateResponse>(indexName, json);
    return response.ApiCall.Success;
}  

希望这可以节省一些时间!

【讨论】:

    猜你喜欢
    • 2019-08-04
    • 2017-04-04
    • 1970-01-01
    • 1970-01-01
    • 2021-07-15
    • 1970-01-01
    • 2018-07-25
    • 1970-01-01
    • 2018-12-21
    相关资源
    最近更新 更多