2015-03-13 49 views
3

我們允許客戶端在創建索引時定義自定義分析器。我們希望在json中指定它,通過底層的ElasticSearch文檔提供最大的靈活性和可理解性。ElasticSearch NEST:通過指定json通過ElasticClient創建索引

我想創建一個索引,使用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然後調用添加(「分析」,JSON)要做到這一點後,但添加不是我正在使用的ElasticSearch庫版本的功能。

我可以想像的選項包括:

  1. 不知何故使用ElasticClient.Raw.IndicesCreatePost或經由IndexSettingsConverter.ReadJson東西類似
  2. 反序列化JSON字符串成IndexSettings對象(),然後將其通過ElasticClient.CreateIndex(ICreateIndexRequest)

這兩種機制都有很少的文檔。

我絕對試圖避免CreateIndex的lambda函數版本,因爲將用戶的json翻譯成lamdba表達式只是爲了立即將它們轉換回JSON深入NEST。

以上#1或#2的其他選項或具體示例非常感謝,因爲解決此問題的建議方法。

+0

你使用哪個版本的NEST? – Rob 2015-03-13 07:46:39

+0

我使用@mcating工作。我們使用Nest版本1.1.2。 – Odrade 2015-03-13 14:38:02

回答

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的建議,並想出瞭如何將任意的json直接應用到ElasticClient.IElasticsearchClient上,以避免對安全和連接細節進行反向工程。

痛苦的努力得出這個結論,如果不處理大量的無證NEST代碼,這是完全不可能的。

+0

Elasticsearch 2.x中缺少_client.Raw.IndiciesCreatePost。現在是_client.LowLevel.IndicesCreatePost – SDeezy 2016-11-04 22:55:29

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

這在某些情況下會起作用,但我們的ElasticSearch實例通過SSL和jetty進行保護。與其創建一個HttpClient然後對權限/連接細節進行反向工程,對我們來說更好的答案是使用已嵌入到ElasticClient實例中的連接細節。感謝您的協助! – mcating 2015-03-16 02:38:48

+0

@mcating沒有什麼不安全的,或者需要使用直接HTTP調用進行反向工程。這就是我們在所有系統中所做的(在Nginx後面)。重複使用我們現有的ES知識要比學習圖書館更容易。這隻能在「某些情況下」才起作用。這就是所有插件和擴展程序的方式,這是我們通過curl與ES進行交互的方式,以及您將通過NEST通過網絡看到的內容。有關詳細信息,請參閱我的內部文檔https://netfxharmonics.com/2015/11/learningelasticps。 – 2016-10-13 21:51:40

+0

@DavidBetz:我的疑慮是概念性的。通過直接訪問HttpClient,您可以瞭解可能隨時間而改變的實現細節。通過堅持ElasticClient(概念上封裝了所有必需的連接細節),客戶端對基礎實施細節的響應變得更加靈活。 – mcating 2016-10-18 22:36:07