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

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

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

Начать курс

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

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

Установка

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

npm install @elastic/elasticsearch

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

npm install -D @types/node

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

Создайте экземпляр клиента, указав URL вашего Elasticsearch сервера. По умолчанию используется порт 9200.

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

const client = new Client({
  node: 'http://localhost:9200',
  // Для облачных кластеров используйте cloud: { id: '...' }
  // auth: { apiKey: '...' } или { username: '...', password: '...' }
});

Типизация ответов

Одно из главных преимуществ TypeScript — возможность типизировать документы. Клиент поддерживает дженерики, что позволяет строго определить структуру данных:

interface Book {
  title: string;
  author: string;
  year: number;
  isbn: string;
  rating?: number; // необязательное поле
}

// Теперь все операции с индексом 'books' будут типизированы
async function addBook(book: Book) {
  const result = await client.index<Book>({
    index: 'books',
    document: book,
  });
  return result;
}

CRUD-операции

Создание/индексация документа

const book: Book = {
  title: 'Война и мир',
  author: 'Лев Толстой',
  year: 1869,
  isbn: '978-5-17-123456-7',
};

const response = await client.index({
  index: 'books',
  id: '1', // опционально, можно не указывать — Elasticsearch сгенерирует ID
  document: book,
});
console.log('Document indexed:', response._id);

Получение документа по ID

const getResponse = await client.get({
  index: 'books',
  id: '1',
});
console.log('Found document:', getResponse._source); // типизировано как Book

Обновление документа

await client.update({
  index: 'books',
  id: '1',
  doc: {
    rating: 4.8, // частичное обновление
  },
});

Удаление документа

await client.delete({
  index: 'books',
  id: '1',
});

Поиск данных

Основной метод для полнотекстового поиска — search. Он принимает Query DSL (Domain Specific Language) Elasticsearch.

interface SearchResult {
  hits: {
    total: { value: number };
    hits: Array<{ _source: Book }>;
  };
}

async function searchBooks(query: string) {
  const result = await client.search<SearchResult>({
    index: 'books',
    query: {
      multi_match: {
        query: query,
        fields: ['title', 'author'], // поиск по нескольким полям
      },
    },
  });

  const books = result.hits.hits.map(hit => hit._source);
  return books;
}

// Использование
const books = await searchBooks('Толстой');
console.log(books); // массив объектов Book

Агрегации

Агрегации позволяют получать статистические данные по индексу, например, количество книг по годам.

async function getBooksByYear() {
  const result = await client.search({
    index: 'books',
    size: 0, // не возвращаем сами документы, только агрегации
    aggs: {
      books_per_year: {
        terms: { field: 'year' },
      },
    },
  });

  const buckets = result.aggregations?.books_per_year?.buckets;
  return buckets?.map(b => ({ year: b.key, count: b.doc_count }));
}

getBooksByYear().then(data => console.log(data));

Пакетная обработка (Bulk API)

Для массовой индексации используйте метод bulk. Это значительно быстрее, чем индексировать каждый документ по отдельности.

const books: Book[] = [
  { title: 'Преступление и наказание', author: 'Ф. Достоевский', year: 1866, isbn: '...' },
  { title: 'Мастер и Маргарита', author: 'М. Булгаков', year: 1966, isbn                    

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