1 юни, 2020

Мартин Тошев

Elasticsearch е едно от най-популярните приложения за търсене в днешно време, което се използва в редица приложения (като Wikipedia, Stackoverflow и много други). Базирано е на Lucene библиотеката за търсене и една от основните функционалности, които предлага е JSON-базиран език за писане на заявки, които е изграден над Lucene и предоставя доста лесен механизъм за взаимодействие с Elasticsearch платформата. Поддръжката за SQL добавена в Elasticsearch 6.3 предоставя стандартен механизъм за изпълнение на заявки за търсене и е стъпка напред към по-лесното използване на Elasticsearch от страна на програмистите.

Въпреки че стандарта SQL е разработен основно за работа с релационни бази данни, той е вече успешно реализиран в редица нерелационни бази данни (каквато е и Elasticsearch). Други такива пример включват например и приложения като Apache Spark или Apache Ignite (където SQL е в основата на самото приложение). В тази статия ще разгледаме накратко как работи Elasticsearch SQL.

Предварителен сетъп

За да изпробвате примерите показани в статияте е необходимо да си инстралирате и стартирате локално Elasticsearch (поне версия 6.3). В статията е използван Elasticsearch 7.5. Първо ще създадем posts индекса, който съхранява постове за даден форум. Ще използваме официалния Elasticsearch Java клиент , за да добавим данни в индекса без да указваме експлицитно схема за полетата в индекса (Elasticsearch ще я създаде за нас автоматично в такъв случай).

Необходимо е да създадем Maven проект със зависимост към Elasticsearch Java high level client библиотеката:

<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.5.0</version>
</dependency>

Ще създадем 10000 генерирани документа в posts индекса като използваме следния код:

RestHighLevelClient client = new RestHighLevelClient(
    RestClient.builder( new HttpHost("localhost", 9200, "http")));

String[] possibleUsers = new String[] {"Martin", "Jim", "John"};
String[] possibleDates = new String[] {"2019-12-15", "2019-12-16", "2019-12-17"};
String[] possibleMessages = new String[] {
    "Hello, Devstyler !",
    "Cool set of blog posts. We want more !",
    "Elasticsearch SQL is great."};

for (int i = 1; i <= 10000; i++) {
    Map<String, Object> jsonMap = new HashMap<>();
    jsonMap.put("user", possibleUsers[ThreadLocalRandom.current().nextInt(0, 3)]);
    jsonMap.put("date", possibleDates[ThreadLocalRandom.current().nextInt(0, 3)]);
    jsonMap.put("message", possibleMessages[ThreadLocalRandom.current().nextInt(0, 3)]);
    IndexRequest request = new IndexRequest("posts")
        .id(String.valueOf(i)).source(jsonMap);
    client.index(request, RequestOptions.DEFAULT);
}
client.close();