Skip to content

kotovi4/terminado

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Монорепо учебного полнотекстового поиска

Тип: in-memory inverted index + простой скоринг (TF * IDF-вариант с нормализованным tf).

Пакеты

  • search-engine – чистое ядро (TypeScript): токенизация, инвертированный индекс, поиск
  • server – HTTP API (Node.js, без фреймворков) поверх ядра
  • web – UI (React + Vite + TypeScript)
  • data – вспомогательные данные (fallback seed)
  • docs – документация (архитектура и т.п.)

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

  • Индексация произвольных документов (строковые поля)
  • Поиск по нескольким термам + fallback подстрочного совпадения (expand)
  • Импорт товаров из DummyJSON (fallback на локальный seed data/products-seed.json)
  • Подсветка терминов (клиент)
  • Удаление / реиндексация документов

Требования

Node.js 18+ (глобальный fetch).

Установка и запуск (dev)

# Установка (соберёт search-engine через prepare)
npm install

# Запуск сервера (порт 4000)
npm run dev:server

# Запуск фронтенда (порт 5173)
npm run dev:web

# Параллельно (Unix шелл)
npm run dev

Открой http://localhost:5173 — кнопка «Импортировать товары» подтянет данные и создаст индекс.

Переменные окружения (web)

Создайте .env.local при необходимости:

VITE_API_BASE=http://localhost:4000

По умолчанию используется http://localhost:4000.

Структура

search-engine/
  src/
    tokenizer.ts
    invertedIndex.ts
    index.ts
    types.ts
server/
  src/index.ts
web/
  src/api.ts
  src/App.tsx
  src/components/ProductCard.tsx
  src/styles.css
data/products-seed.json
docs/ARCHITECTURE.md

API (порт 4000)

Метод Путь Параметры Описание
GET /search q, limit, expand=0/1 Поиск
GET /products limit, offset, category Листинг
POST /index body JSON Индексация
POST /delete { id } Удаление
GET /stats Количество документов
POST /import/products Импорт (DummyJSON/seed)
POST /reset Сброс индекса
GET /health Health-check

Примеры

curl -X POST http://localhost:4000/import/products
curl 'http://localhost:4000/search?q=phone'
curl -X POST http://localhost:4000/index -H 'Content-Type: application/json' -d '{"title":"Пример","body":"Тестовый документ"}'

Использование ядра напрямую (@search/engine)

import { InvertedIndex } from '@search/engine';

const idx = new InvertedIndex();
idx.addDocument({ id: '1', title: 'Поисковый движок', body: 'Учебный пример инвертированного индекса' });
idx.addDocument({ id: '2', title: 'Алгоритмы', body: 'Структуры данных и индекс' });
const hits = idx.search('индекс движок');
console.log(hits.map(h => ({ id: h.id, score: h.score })));

Реализация

  • Инвертированный индекс: Map(term -> Map(docId -> freq))
  • Нормализация TF: tf / docLength
  • IDF: log(1 + N / (df + 1))
  • Подстрочное расширение: если терм не найден и длина >= 3 — поиск включает термы содержащие подстроку (лимитируется)
  • Токенизация: Unicode lower-case + фильтрация русских стоп-слов

Ограничения

  • Всё в памяти (нет persist)
  • Нет позиционных списков (нет поиска фраз)
  • Удаление O(T) по количеству термов
  • Скоринг упрощённый (не BM25)

Roadmap

  1. BM25
  2. Позиции и фразовый поиск
  3. Snapshot / WAL
  4. Иммутабельные сегменты + merge
  5. Фильтры (числовые/диапазоны)
  6. Bulk индексация
  7. Кэш статистик термов
  8. Репликация (WAL + restore)
  9. Server-side snippets
  10. Unit / интеграционные тесты + бенчмарки

Продакшн сборка

npm run build
# Результат:
#  server/dist  (Node JS)
#  web/dist     (статические файлы)

Далее отдавайте web/dist любым статик-сервером и запускайте node server/dist/index.js.

Legacy

Старые файлы (vanilla JS сервер/клиент) удалены / заглушены. Актуальный код — только в пакетах search-engine, server, web.

Отладка

  1. npm run dev:server
  2. npm run dev:web
  3. Импорт → поиск → проверка /stats

Лицензия

MIT (учебный пример).

About

A lightweight, in-memory full-text search microservice

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors