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

时间:2015-03-13 06:17:38

标签: c# elasticsearch nest

我们允许客户在创建索引时定义自定义分析器。我们希望在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

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

我能想象的选项包括:

  1. 以某种方式使用ElasticClient.Raw.IndicesCreatePost或类似的东西
  2. 通过IndexSettingsConverter.ReadJson()将json字符串反序列化为IndexSettings对象,然后通过ElasticClient.CreateIndex(ICreateIndexRequest)应用它
  3. 这两种机制都有很少的文档。

    我绝对试图避免使用CreateIndex的lambda函数版本,因为将用户的json转换为lamdba表达式会很麻烦,只是在NEST中将它们立即转换回json。

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

3 个答案:

答案 0 :(得分:7)

最简单的解决方案是从原始问题中实施选项#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'建议并想出如何直接对ElasticClient.IElasticsearchClient应用任意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更改内容变量。

答案 2 :(得分:0)

好的,在更新到Elasticsearch NEST v6.0.2后,我不得不修改我的代码,并希望将其发布给其他人。更改包括将CREATE OR REPLACE PACKAGE BODY mahalanobis_distance_package AS --max_d NUMBER; --TYPE tbNumber IS TABLE OF NUMBER INDEX BY PLS_INTEGER; function rel_mahalanobis_distance_aux_3( A NUMBER, B1 NUMBER,B2 NUMBER,B3 NUMBER) RETURN tbNumber IS tbNumber_obj tbNumber; BEGIN max_d := 0; FOR j IN 1..3 LOOP tbNumber_obj(j) := 0; END LOOP; tbNumber_obj(1) := ABS(A - B1); IF tbNumber_obj(1) > max_d THEN max_d := tbNumber_obj(1); END IF; tbNumber_obj(2) := ABS(A - B2); IF tbNumber_obj(2) > max_d THEN max_d := tbNumber_obj(2); END IF; tbNumber_obj(3) := ABS(A - B3); IF tbNumber_obj(3) > max_d THEN max_d := tbNumber_obj(3); END IF; return tbNumber_obj; END rel_mahalanobis_distance_aux_3; END mahalanobis_distance_package; / 作为函数的类型传递,并在响应中使用CreateResponse属性。

ApiCall

希望这能节省时间!