Files
Baradb/docs/bg/fts.md
T
dimgigov ef264d7d69
CI / test (push) Has been cancelled
CI / verify (push) Has been cancelled
Clients CI / build-server (push) Has been cancelled
Clients CI / test-python (push) Has been cancelled
Clients CI / test-javascript (push) Has been cancelled
Clients CI / test-nim (push) Has been cancelled
Clients CI / test-rust (push) Has been cancelled
feat: add unified search engine — HNSW heap-opt, segment index, boolean/phrase/ngram/facet
New src/barabadb/search/ module with 9 components:
- priority_queue.nim: BoundedHeap for O(log n) search
- hnsw_opt.nim: heap-based searchLayer (2.4x faster, 92-99% recall@10)
- inverted.nim: segment-based index with soft-delete and compaction
- phrase.nim: positional phrase + proximity search
- boolean.nim: recursive descent parser (AND/OR/NOT/ranges/wildcards)
- ngram.nim: trigram index for O(1) fuzzy/prefix/wildcard
- stemmer.nim: Porter2 stemmers (EN/BG/DE/FR/RU)
- facet.nim: faceted search with filter pushdown
- engine.nim: UnifiedSearchEngine combining all search types

Performance (dim=128, efConstruction=200):
  N=1K:   0.30ms search, 99.6% recall@10
  N=10K:  1.09ms search, 92.6% recall@10
  N=50K:  2.26ms search, 75.5% recall@10

Includes search benchmarks (benchmarks/search_bench.nim), updated docs
(en/bg fts.md, en/bg search.md), and crossmodal engine integration.
2026-05-30 13:42:08 +03:00

7.4 KiB
Raw Blame History

Full-Text Search Engine

Inverted индекс с BM25 и TF-IDF ранжиране за текстово търсене.

Употреба

import barabadb/fts/engine

var idx = newInvertedIndex()
idx.addDocument(1, "Nim is a fast programming language")
idx.addDocument(2, "Python is popular for data science")

# BM25 търсене
let results = idx.search("programming language")

# TF-IDF търсене
let tfidf = idx.searchTfidf("programming language")

# Fuzzy търсене (толеранс на печатни грешки)
let fuzzy = idx.fuzzySearch("programing", maxDistance = 2)

# Wildcard търсене
let wild = idx.regexSearch("prog*")

Методи за Ранжиране

BM25

Best matching алгоритъм за ранжиране:

let bm25 = idx.searchBM25("query terms")

TF-IDF

Term Frequency-Inverse Document Frequency:

let tfidf = idx.searchTfidf("query terms")

Функции за Търсене

Функция Описание
Fuzzy търсене Levenshtein distance толеранс
Wildcard Префиксни, суфиксни и инфиксни wildcards
Regex Регулярни изрази
Фразово търсене Точно съвпадение на фраза с поддръжка на slop
Proximity търсене Термини в рамките на конфигурируемо разстояние
Булево AND, OR, NOT оператори с вложени изрази
Фасетно търсене Филтриране по категории, бройки и агрегация
Хибридно търсене Комбинирано пълнотекстово + векторно (HNSW) с RRF сливане
Сегментно индексиране Инкрементално индексиране с автоматично уплътняване
Полетно усилване Тегла за релевантност по поле

SQL Интерфейс

Пълнотекстовото търсене е достъпно и директно в BaraQL:

-- Създаване на таблица с текстова колона
CREATE TABLE articles (id INT PRIMARY KEY, title TEXT, body TEXT);

-- Създаване на FTS индекс
CREATE INDEX idx_fts ON articles(body) USING FTS;

-- Търсене с оператора @@ (BM25 ранжиране)
SELECT * FROM articles WHERE body @@ 'machine learning';

-- Търсене с множество термини
SELECT * FROM articles WHERE body @@ 'quick brown fox';

Многоезична Поддръжка

import barabadb/fts/multilang

# Поддържани езици: EN, BG, DE, FR, RU
var tokenizer = newTokenizer("bg")  # Български
let tokens = tokenizer.tokenize("Търсене в пълен текст")

Функции за всеки език:

  • Токенизация
  • Stop думи
  • Стеминг
  • Детекция на език

Разширено Търсене

Новият модул src/barabadb/search/ предоставя унифицирана търсачка със сегментно-базирано индексиране за високопроизводителни операции за търсене.

UnifiedSearchEngine

import barabadb/search/engine

# Създаване на търсачка с конфигурация по подразбиране
var engine = newUnifiedSearchEngine()

# Индексиране на документи с полета и фасети
engine.indexDocument(
  docId = 1,
  text = "Nim е бърз програмен език",
  fields = {"title": "Преглед на Nim"}.toTable,
  facets = {"category": @["програмиране"], "level": @["начинаещо"]}.toTable
)

# Основно търсене
let results = engine.search("програмен език", limit = 10)

# Фразово търсене (точно съвпадение на фраза)
let phrase = engine.searchPhrase(@["бърз", "програмен"], slop = 0)

# Proximity търсене (термини в рамките на разстояние)
let proximity = engine.searchProximity(@["бърз", "език"], maxDistance = 5)

# Булеви заявки
let boolResults = engine.searchBoolean("програмиране AND (бърз OR ефективен)")
let boolResults2 = engine.searchBoolean("Nim AND NOT Python")
let boolResults3 = engine.searchBoolean("\"точна фраза\" OR wildcard*")

# Fuzzy търсене с толеранс на печатни грешки
let fuzzy = engine.searchFuzzy("програмиране", maxDistance = 2)

# Търсене по префикс и wildcard
let prefix = engine.searchPrefix("прог", limit = 10)
let wildcard = engine.searchWildcard("прог*", limit = 10)

Фасетно Търсене

import barabadb/search/engine
import std/sets

# Индексиране на документи с фасети
engine.indexDocument(
  docId = 1,
  text = "Nim урок",
  facets = {"category": @["програмиране", "урок"], "difficulty": @["начинаещо"]}.toTable
)

# Получаване на бройки по фасети
let counts = engine.getFacetCounts("category", limit = 10)
for count in counts:
  echo count.value, ": ", count.count

# Филтриране по фасети
var filters = @[
  FacetFilter(field: "category", values: @["програмиране"], exclude: false),
  FacetFilter(field: "difficulty", values: @["напреднало"], exclude: true)
]
let matchingDocs = engine.filterByFacets(filters)

# Агрегация на множество фасети
let agg = engine.facets.aggregate(@["category", "difficulty"], matchingDocs)

Хибридно Търсене (Текст + Вектор)

import barabadb/search/engine
import barabadb/vector/engine

# Индексиране на вектори
engine.indexVector(1, @[0.1, 0.2, 0.3], {"title": "Документ 1"}.toTable)

# Хибридно търсене комбиниращо текст и векторна сходност
let hybrid = engine.hybridSearch(
  queryText = "програмиране",
  queryVec = @[0.1, 0.2, 0.3],
  k = 10,
  textWeight = 1.0,
  vecWeight = 1.0
)

# Филтрирано векторно търсене
proc filterMeta(meta: Table[string, string]): bool =
  meta.getOrDefault("category") == "програмиране"

let filtered = engine.searchVectorFiltered(@[0.1, 0.2, 0.3], k = 10, filterMeta)

Конфигурация и Управление

# Персонализирана конфигурация
var config = defaultSearchConfig()
config.language = langBulgarian
config.maxSegmentSize = 100_000
config.ngramSize = 3
config.enableFacets = true

var engine = newUnifiedSearchEngine(config)

# Задаване на полетно усилване за настройка на релевантността
engine.setFieldBoost("title", 2.0)
engine.setFieldBoost("body", 1.0)

# Смяна на езика
engine.setLanguage(langBulgarian)

# Уплътняване на сегменти за по-добра производителност
engine.compact()

# Получаване на статистика
echo "Документи: ", engine.documentCount()
echo "Термини: ", engine.termCount()

# Премахване на документи
engine.removeDocument(1)