Руководство по Elasticsearch в Java

Руководство по Elasticsearch в Java

1. обзор

В этой статье мы собираемся погрузиться в некоторые ключевые концепции, связанные с полнотекстовыми поисковыми системами, с особым акцентом на Elasticsearch.

Поскольку это статья, ориентированная на Java, мы не собираемся давать подробное пошаговое руководство о том, как настроить Elasticsearch и показывать, как он работает под капотом, вместо этого мы собираемся настроить таргетинг на клиент Java, и как использовать основные функции, такие какindex,delete,get иsearch.

2. Настроить

Чтобы установить Elasticsearch на свой компьютер, обратитесь кofficial setup guide.

Процесс установки довольно прост, просто загрузите пакет zip / tar и запустите файл сценарияelasticsearch (elasticsearch.bat для пользователей Windows).

По умолчанию Elasticsearch прослушивает порт 9200 для ожидающих HTTP-запросов по умолчанию. Мы можем убедиться, что он успешно запущен, открыв URL-адресhttp://localhost:9200/ в вашем любимом браузере:

{
  "name" : "GEpcsab",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "z3FfAe6gRMmSmeWBIOihJg",
  "version" : {
    "number" : "5.6.10",
    "build_hash" : "b727a60",
    "build_date" : "2018-06-06T15:48:34.860Z",
    "build_snapshot" : false,
    "lucene_version" : "6.6.1"
  },
  "tagline" : "You Know, for Search"
}

3. Конфигурация Maven

Теперь, когда у нас есть наш базовый кластер Elasticsearch, давайте перейдем непосредственно к клиенту Java. Прежде всего, нам нужно, чтобы следующийMaven dependency был объявлен в нашем файлеpom.xml:


    org.elasticsearch
    elasticsearch
    5.6.0

Вы всегда можете проверить последние версии, размещенные на Maven Central, по ссылке, указанной ранее.

4. Java API

Прежде чем мы сразу перейдем к тому, как использовать основные функции Java API, нам нужно запустить транспортный клиент:

Client client = new PreBuiltTransportClient(
  Settings.builder().put("client.transport.sniff", true)
                    .put("cluster.name","elasticsearch").build())
  .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9300));

4.1. Индексирование документов

ФункцияprepareIndex() позволяет сохранить произвольный документ JSON и сделать его доступным для поиска:

@Test
public void givenJsonString_whenJavaObject_thenIndexDocument() {
    String jsonObject = "{\"age\":10,\"dateOfBirth\":1471466076564,"
      +"\"fullName\":\"John Doe\"}";
    IndexResponse response = client.prepareIndex("people", "Doe")
      .setSource(jsonObject, XContentType.JSON).get();

    String id = response.getId();
    String index = response.getIndex();
    String type = response.getType();
    long version = response.getVersion();

    assertEquals(Result.CREATED, response.getResult());
    assertEquals(0, version);
    assertEquals("people", index);
    assertEquals("Doe", type);
}

При запуске теста обязательно объявите переменнуюpath.home, иначе может возникнуть следующее исключение:

java.lang.IllegalStateException: path.home is not configured

После выполнения команды Maven:mvn clean install -Des.path.home=C:\elastic документ JSON будет сохранен сpeople в качестве индекса иDoe в качестве типа.

Обратите внимание, что можно использоватьany JSON Java library для создания и обработки ваших документов. If you are not familiar with any of these, you can use Elasticsearch helpers to generate your own JSON documents:

XContentBuilder builder = XContentFactory.jsonBuilder()
  .startObject()
  .field("fullName", "Test")
  .field("dateOfBirth", new Date())
  .field("age", "10")
  .endObject();
IndexResponse response = client.prepareIndex("people", "Doe")
  .setSource(builder).get();

assertEquals(Result.CREATED, response.getResult());

4.2. Запрос проиндексированных документов

Теперь, когда у нас есть проиндексированный типизированный документ JSON с возможностью поиска, мы можем продолжить поиск, используя методprepareSearch():

SearchResponse response = client.prepareSearch().execute().actionGet();
List searchHits = Arrays.asList(response.getHits().getHits());
List results = new ArrayList();
searchHits.forEach(
  hit -> results.add(JSON.parseObject(hit.getSourceAsString(), Person.class)));

The results returned by the actionGet() method are called Hits, каждыйHit относится к документу JSON, соответствующему поисковому запросу.

В этом случае списокresults содержит все данные, хранящиеся в кластере. Обратите внимание, что в этом примере мы используем библиотекуFastJson для преобразования JSONStrings в объекты Java.

Мы можем улучшить запрос, добавив дополнительные параметры, чтобы настроить запрос с помощью методовQueryBuilders:

SearchResponse response = client.prepareSearch()
  .setTypes()
  .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
  .setPostFilter(QueryBuilders.rangeQuery("age").from(5).to(15))
  .execute()
  .actionGet();

4.3. Получение и удаление документов

МетодыprepareGet() иprepareDelete() позволяют получить или удалить документ JSON из кластера по его идентификатору:

GetResponse response = client.prepareGet("people","Doe","1").get();
String age = (String) response.getField("age").getValue();
// Process other fields
DeleteResponse response = client.prepareDelete("people", "Doe", "5")
  .get();

Синтаксис довольно прост, вам просто нужно указать индекс и значение типа вместе с идентификатором объекта.

5. QueryBuilders Примеры

КлассQueryBuilders предоставляет множество статических методов, используемых в качестве динамических сопоставителей для поиска определенных записей в кластере. Используя методprepareSearch() для поиска определенных документов JSON в кластере, мы можем использовать построители запросов для настройки результатов поиска.

Вот список наиболее частых применений APIQueryBuilders.

МетодmatchAllQuery() возвращает объектQueryBuilder, соответствующий всем документам в кластере:

QueryBuilder matchAllQuery = QueryBuilders.matchAllQuery();

rangeQuery() соответствует документам, в которых значение поля находится в определенном диапазоне:

QueryBuilder matchDocumentsWithinRange = QueryBuilders
  .rangeQuery("price").from(15).to(100)

Предоставление имени поля - например, fullName, и соответствующее значение - например, John Doe, методmatchQuery() сопоставляет весь документ с этим точным значением поля:

QueryBuilder matchSpecificFieldQuery= QueryBuilders
  .matchQuery("fullName", "John Doe");

Мы также можем использовать методmultiMatchQuery() для создания версии запроса на совпадение с несколькими полями:

QueryBuilder matchSpecificFieldQuery= QueryBuilders.matchQuery(
  "Text I am looking for", "field_1", "field_2^3", "*_field_wildcard");

We can use the caret symbol (^) to boost specific fields.

В нашем примере дляfield_2 установлено значение повышения, равное трем, что делает его более важным, чем другие поля. Обратите внимание, что можно использовать подстановочные знаки и запросы с регулярными выражениями, но с точки зрения производительности, остерегайтесь потребления памяти и задержки времени ответа при работе с подстановочными знаками, потому что что-то вроде * _apples может оказать огромное влияние на производительность.

Коэффициент важности используется для упорядочивания результирующего набора совпадений, возвращаемых после выполнения методаprepareSearch().

Если вы более знакомы с синтаксисом запросов Lucene, вы можете использоватьsimpleQueryStringQuery() method to customize search queries:

QueryBuilder simpleStringQuery = QueryBuilders
  .simpleQueryStringQuery("+John -Doe OR Janette");

Как вы, наверное, догадались,we can use the Lucene’s Query Parser syntax to build simple, yet powerful queries. Вот несколько основных операторов, которые можно использовать вместе с операторамиAND/OR/NOT для построения поисковых запросов:

  • Требуемый оператор (+): требует, чтобы определенный фрагмент текста существовал где-то в полях документа.

  • Оператор запрета (): исключает все документы, содержащие ключевое слово, объявленное после символа ().

6. Заключение

В этой быстрой статье мы увидели, как использовать Java API ElasticSearch для выполнения некоторых общих функций, связанных с системами полнотекстового поиска.

Вы можете ознакомиться с примером из этой статьи вGitHub project.

Related