ElasticSearch NEST:通过指定 json 通过 ElasticClient 创建索引

ElasticSearch NEST: Create an index through ElasticClient by specifying json

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

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

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

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

我能想到的选项包括:

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

这两种机制的文档都很少。

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

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

如果你想做你上面描述的那样的事情,那么你可以简单地使用一个 HttpClient 并将创建索引的请求发送到你的 elasticsearch 服务器。在这种情况下,您可以在请求的内容中包含您的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);
                }
            }
        }

此特定代码段将使用一个分片、一个副本(默认)以及默认设置和映射创建到指定端点的索引。使用 json.

更改内容变量

最简单的解决方案是实施原始问题中的选项 #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 代码,这是完全不可能的。

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

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

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