Elasticsearch клиент для Go (Golang): полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Elasticsearch клиент для Go (Golang): мощный инструмент для работы с поисковым движком

Elasticsearch — это распределённая, полнотекстовая поисковая система, построенная на Apache Lucene. Для эффективного взаимодействия с ней из приложений на Go (Golang) используется официальный клиент go-elasticsearch. Эта библиотека предоставляет удобный и производительный API для выполнения всех основных операций: от индексации документов до сложных аналитических запросов.

В этой статье мы подробно разберём возможности библиотеки, её установку, настройку и приведём практические примеры кода на Go.

Основные возможности go-elasticsearch

  • Полная поддержка REST API Elasticsearch — работа с индексами, документами, поиском, агрегациями и управлением кластером.
  • Типобезопасные запросы — использование структур Go для построения JSON-запросов.
  • Автоматическое управление соединениями — пул соединений, повторные попытки при ошибках, балансировка нагрузки.
  • Поддержка bulk-операций — массовая индексация и обновление документов.
  • Интеграция с контекстами Go — отмена запросов и таймауты.
  • Лёгкая настройка — кастомные HTTP-клиенты, логирование, сжатие.

Установка

Для установки библиотеки выполните команду в терминале:

go get github.com/elastic/go-elasticsearch/v8

Убедитесь, что ваша версия Go не ниже 1.18. Если вы используете более старую версию Elasticsearch (например, 7.x), установите соответствующую версию клиента:

go get github.com/elastic/go-elasticsearch/v7

Базовое подключение и настройка

Для начала работы создайте клиент, указав адрес Elasticsearch сервера:

package main

import (
    "log"
    "github.com/elastic/go-elasticsearch/v8"
)

func main() {
    cfg := elasticsearch.Config{
        Addresses: []string{
            "http://localhost:9200",
        },
        // Если требуется аутентификация:
        // Username: "elastic",
        // Password: "changeme",
    }

    es, err := elasticsearch.NewClient(cfg)
    if err != nil {
        log.Fatalf("Ошибка создания клиента: %s", err)
    }

    // Проверка соединения
    res, err := es.Info()
    if err != nil {
        log.Fatalf("Ошибка получения информации: %s", err)
    }
    defer res.Body.Close()

    log.Println(res.String())
}

Индексация документов

Для добавления документа в индекс используется метод Index() или Create(). Рассмотрим пример с типизированными данными:

type Article struct {
    ID      int      `json:"id"`
    Title   string   `json:"title"`
    Content string   `json:"content"`
    Tags    []string `json:"tags"`
    Date    string   `json:"date"`
}

func indexArticle(es *elasticsearch.Client, article Article) error {
    body, err := json.Marshal(article)
    if err != nil {
        return err
    }

    req := esapi.IndexRequest{
        Index:      "articles",
        DocumentID: strconv.Itoa(article.ID),
        Body:       strings.NewReader(string(body)),
        Refresh:    "true", // для немедленного обновления
    }

    res, err := req.Do(context.Background(), es)
    if err != nil {
        return err
    }
    defer res.Body.Close()

    if res.IsError() {
        return fmt.Errorf("ошибка индексации: %s", res.String())
    }

    return nil
}

Поиск документов

Для выполнения поисковых запросов используется метод Search(). Пример полнотекстового поиска:

func searchArticles(es *elasticsearch.Client, query string) ([]Article, error) {
    var buf bytes.Buffer
    searchQuery := map[string]interface{}{
        "query": map[string]interface{}{
            "match": map[string]interface{}{
                "content": query,
            },
        },
    }
    if err := json.NewEncoder(&buf).Encode(searchQuery); err != nil {
        return nil, err
    }

    res, err := es.Search(
        es.Search.WithIndex("articles"),
        es.Search.WithBody(&buf),
        es.Search.WithTrackTotalHits(true),
        es.Search.WithPretty(),
    )
    if err != nil {
        return nil, err
    }
    defer res.Body.Close()

    var result map[string]interface{}
    if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
        return nil, err
    }

    // Парсинг результатов
    hits := result["hits"].(map[string]interface{})["hits"].([]interface{})
    var articles []Article
    for _, hit := range hits {
        source := hit.(map[string]interface{})["_source"]
        var article Article
        data, _ := json.Marshal(source)
        json.Unmarshal(data, &article)
        articles = append(                    

Рекомендаций