2015-03-13 6 views
3

Мы разрешаем клиенту определять пользовательские анализаторы в момент создания индекса. Мы бы предпочли указать это в json, чтобы обеспечить максимальную гибкость и понятность через базовую документацию ElasticSearch.ElasticSearch NEST: Создайте индекс через ElasticClient, указав json

Я хотел бы создать индекс, используя произвольное описание анализаторов, карт и т. Д., Определенных в строке 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 («анализ», JSON), но Add не является функцией для используемой мной версии библиотеки ElasticSearch.

варианты я могу себе представить, включает в себя:

  1. Как-то с помощью ElasticClient.Raw.IndicesCreatePost или что-то аналогичного
  2. Десериализации строки JSON в IndexSettings объекта через IndexSettingsConverter.ReadJson(), и последующее применение через ElasticClient.CreateIndex (ICreateIndexRequest)

Оба эти механизма имеют очень скудную документацию.

Я абсолютно стараюсь избегать версий функции лямбда-функции CreateIndex, так как было бы ужасно перевести json пользователя в выражения lamdba, только чтобы сразу перевести их обратно в json глубоко в NEST.

Другие варианты или конкретные примеры # 1 или # 2, приведенные выше, очень ценятся, как рекомендуемый подход к решению этой проблемы.

+0

Какую версию NEST вы используете? – Rob

+0

Я работаю с @mcating. Мы используем версию Nest 1.1.2. – Odrade

ответ

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. Чувствуя кроличью нору, я взял предложение Манолиса и понял, как применить произвольный json непосредственно к ElasticClient.IElasticsearchClient, чтобы избежать необходимости перепроектировать данные о безопасности и подключении.

Болезненное усилие, чтобы прийти к такому выводу и полностью невозможно без работы с большим количеством недокументированного кода NEST.

+0

_client.Raw.IndiciesCreatePost отсутствует в Elasticsearch 2.x. Теперь это _client.LowLevel.IndicesCreatePost – SDeezy

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 и причал. Вместо того, чтобы создавать HttpClient, а затем реконструировать данные о разрешении/подключении, лучшим ответом для нас является использование данных соединения, уже встроенных в экземпляр ElasticClient. Спасибо за помощь! – mcating

+0

@mcating Нет ничего небезопасного или требует обратной инженерии, используя прямые HTTP-вызовы. Это то, что мы делаем во всех наших системах (за Nginx). Это просто проще повторно использовать наши знания в области ЭС, чем изучать библиотеку. В этом нет ничего, что могло бы работать только в «некоторых случаях». Вот как все плагины и расширения, как мы все взаимодействуем с ES с завитом, и это то, что вы увидите по проводке с помощью NEST. Дополнительную информацию см. В документе моих внутренних документов по адресу https://netfxharmonics.com/2015/11/learningelasticps. –

+0

@DavidBetz: Моя забота концептуальна. Переходя непосредственно к HttpClient, вы раскрываете себе детали реализации, которые со временем могут меняться. Придерживаясь ElasticClient, который концептуально инкапсулирует все необходимые детали соединения, клиент становится более устойчивым к основным деталям реализации. – mcating