Elasticsearch клиент для TypeScript: @elastic/elasticsearch

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

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

Начать курс

Elasticsearch клиент для TypeScript (@elastic/elasticsearch)

В современной веб-разработке полнотекстовый поиск и анализ данных стали неотъемлемой частью многих приложений. Elasticsearch — это мощная распределенная поисковая система, построенная на базе Apache Lucene. Для работы с ней из TypeScript-приложений (как на сервере Node.js, так и в браузере) используется официальный клиент @elastic/elasticsearch. В этой статье мы подробно разберем его установку, настройку и основные возможности.

Что такое @elastic/elasticsearch?

@elastic/elasticsearch — это официальный, высокопроизводительный клиент для Elasticsearch, написанный на TypeScript. Он предоставляет полный набор API для взаимодействия с кластером Elasticsearch, включая:

  • Индексацию и удаление документов
  • Полнотекстовый поиск с поддержкой сложных запросов
  • Агрегации для анализа данных (группировка, статистика)
  • Управление индексами и маппингом
  • Поддержку пула соединений, повторных попыток и балансировки нагрузки

Благодаря полной поддержке TypeScript, вы получаете автодополнение, проверку типов и документацию прямо в IDE.

Установка

Для начала работы установите пакет через npm или yarn:

npm install @elastic/elasticsearch
# или
yarn add @elastic/elasticsearch

Если вы используете TypeScript, дополнительные типы устанавливать не нужно — они уже встроены в пакет.

Подключение и настройка клиента

Создайте экземпляр клиента, указав URL вашего Elasticsearch-кластера:

import { Client } from '@elastic/elasticsearch';

const client = new Client({
  node: 'http://localhost:9200', // или облачный endpoint
  auth: {
    username: 'elastic',
    password: 'changeme'
  },
  // Для продакшена рекомендуется использовать TLS
  tls: {
    rejectUnauthorized: false // только для разработки!
  }
});

Для облачных развертываний (Elastic Cloud) используйте cloud.id и auth.apiKey:

const client = new Client({
  cloud: {
    id: 'my-cluster:dXMtZWFzdD...'
  },
  auth: {
    apiKey: 'base64EncodedApiKey'
  }
});

Основные операции

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

Добавление нового документа в индекс:

interface Product {
  id: number;
  name: string;
  description: string;
  price: number;
  tags: string[];
}

async function indexProduct(product: Product) {
  const response = await client.index({
    index: 'products',
    id: String(product.id),
    body: product,
    refresh: 'wait_for' // дождаться обновления индекса
  });
  console.log('Document indexed:', response.result);
}

indexProduct({
  id: 1,
  name: 'Ноутбук Lenovo ThinkPad',
  description: 'Мощный ноутбук для разработки',
  price: 1200,
  tags: ['электроника', 'ноутбуки']
});

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

Простой полнотекстовый поиск по полю description:

async function searchProducts(query: string) {
  const response = await client.search({
    index: 'products',
    body: {
      query: {
        match: {
          description: query
        }
      },
      // Пагинация
      from: 0,
      size: 10
    }
  });

  const hits = response.hits.hits.map(hit => hit._source);
  console.log('Found products:', hits);
  return hits;
}

searchProducts('ноутбук разработка');

3. Агрегации

Группировка товаров по тегам:

async function aggregateByTags() {
  const response = await client.search({
    index: 'products',
    body: {
      size: 0, // не возвращаем сами документы
      aggs: {
        by_tag: {
          terms: {
            field: 'tags.keyword',
            size: 20
          }
        }
      }
    }
  });

  const buckets = response.aggregations?.by_tag?.buckets || [];
  console.log('Tags distribution:', buckets);
}

aggregateByTags();

4. Bulk-операции (массовая индексация)

Для загрузки тысяч документов используйте bulk API:

async function bulkIndex(products: Product[]) {
  const body = products.flatMap(product => [
    { index: { _index: 'products', _id: String(product.id) } },
    product
  ]);

  const response = await client.bulk({
    refresh: true,
    body
  });

  if (response.errors) {
    console.error('Bulk errors:', response.items.filter(item => item.index?.error));
  } else {
    console.log('Bulk indexed successfully');
  }
}

Обработка ошибок и повторные попытки

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