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');
}
}