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