This commit is contained in:
243
docs/search-system.md
Normal file
243
docs/search-system.md
Normal file
@@ -0,0 +1,243 @@
|
||||
# 🔍 Система поиска Discours
|
||||
|
||||
## Обзор
|
||||
|
||||
Система поиска Discours использует **семантические эмбединги** для точного поиска по публикациям. Реализована на базе `SentenceTransformers` с поддержкой русского языка и FDE (Fast Document Encoding) для оптимизации.
|
||||
|
||||
## 🚀 Основные возможности
|
||||
|
||||
### **1. Семантический поиск**
|
||||
- Понимание смысла запросов, а не только ключевых слов
|
||||
- Поддержка русского и английского языков
|
||||
- Векторное представление документов через SentenceTransformers
|
||||
|
||||
### **2. Оптимизированная индексация**
|
||||
- Batch-обработка для больших объёмов данных
|
||||
- Тихий режим для массовых операций
|
||||
- FDE кодирование для сжатия векторов
|
||||
|
||||
### **3. Высокая производительность**
|
||||
- Косинусное сходство для ранжирования
|
||||
- Кеширование результатов
|
||||
- Асинхронная обработка
|
||||
|
||||
## 📋 API
|
||||
|
||||
### GraphQL запросы
|
||||
|
||||
```graphql
|
||||
# Поиск по публикациям
|
||||
query SearchShouts($text: String!, $options: ShoutsOptions) {
|
||||
load_shouts_search(text: $text, options: $options) {
|
||||
id
|
||||
title
|
||||
body
|
||||
topics {
|
||||
title
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Поиск по авторам
|
||||
query SearchAuthors($text: String!, $limit: Int, $offset: Int) {
|
||||
load_authors_search(text: $text, limit: $limit, offset: $offset) {
|
||||
id
|
||||
name
|
||||
email
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Параметры поиска
|
||||
|
||||
```python
|
||||
options = {
|
||||
"limit": 10, # Количество результатов
|
||||
"offset": 0, # Смещение для пагинации
|
||||
"filters": { # Дополнительные фильтры
|
||||
"community": 1,
|
||||
"status": "published"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🛠️ Техническая архитектура
|
||||
|
||||
### Компоненты системы
|
||||
|
||||
```
|
||||
📦 Search System
|
||||
├── 🧠 SentenceTransformer # Генерация эмбедингов
|
||||
├── 🗜️ Muvera FDE # Сжатие векторов
|
||||
├── 🗃️ MuveraWrapper # Хранение и поиск
|
||||
└── 🔍 SearchService # API интерфейс
|
||||
```
|
||||
|
||||
### Модель эмбедингов
|
||||
|
||||
**Основная модель**: `paraphrase-multilingual-MiniLM-L12-v2`
|
||||
- Поддержка 50+ языков включая русский
|
||||
- Размерность: 384D
|
||||
- Fallback: `all-MiniLM-L6-v2`
|
||||
|
||||
### Процесс индексации
|
||||
|
||||
```python
|
||||
# 1. Извлечение текста
|
||||
doc_content = f"{title} {subtitle} {lead} {body}".strip()
|
||||
|
||||
# 2. Генерация эмбединга
|
||||
embedding = encoder.encode(doc_content)
|
||||
|
||||
# 3. FDE кодирование
|
||||
compressed = muvera.encode_fde(embedding, buckets=128, method="avg")
|
||||
|
||||
# 4. Сохранение в индекс
|
||||
embeddings[doc_id] = compressed
|
||||
```
|
||||
|
||||
### Алгоритм поиска
|
||||
|
||||
```python
|
||||
# 1. Эмбединг запроса
|
||||
query_embedding = encoder.encode(query_text)
|
||||
query_fde = muvera.encode_fde(query_embedding, buckets=128, method="avg")
|
||||
|
||||
# 2. Косинусное сходство
|
||||
for doc_id, doc_embedding in embeddings.items():
|
||||
similarity = cosine_similarity(query_fde, doc_embedding)
|
||||
results.append({"id": doc_id, "score": similarity})
|
||||
|
||||
# 3. Ранжирование
|
||||
results.sort(key=lambda x: x["score"], reverse=True)
|
||||
```
|
||||
|
||||
## ⚙️ Конфигурация
|
||||
|
||||
### Переменные окружения
|
||||
|
||||
```bash
|
||||
# Поиск
|
||||
MUVERA_INDEX_NAME=discours_search
|
||||
SEARCH_MAX_BATCH_SIZE=100
|
||||
SEARCH_PREFETCH_SIZE=200
|
||||
SEARCH_CACHE_ENABLED=true
|
||||
SEARCH_CACHE_TTL_SECONDS=600
|
||||
```
|
||||
|
||||
### Настройки производительности
|
||||
|
||||
```python
|
||||
# Batch размеры
|
||||
SINGLE_DOC_THRESHOLD = 10 # Меньше = одиночная обработка
|
||||
BATCH_SIZE = 32 # Размер batch для SentenceTransformers
|
||||
FDE_BUCKETS = 128 # Количество bucket для сжатия
|
||||
|
||||
# Logging
|
||||
SILENT_BATCH_MODE = True # Тихий режим для batch операций
|
||||
DEBUG_SINGLE_DOCS = True # Подробные логи для одиночных документов
|
||||
```
|
||||
|
||||
## 🔧 Использование
|
||||
|
||||
### Индексация новых документов
|
||||
|
||||
```python
|
||||
from services.search import search_service
|
||||
|
||||
# Одиночный документ
|
||||
search_service.index(shout)
|
||||
|
||||
# Batch индексация (тихий режим)
|
||||
await search_service.bulk_index(shouts_list)
|
||||
```
|
||||
|
||||
### Поиск
|
||||
|
||||
```python
|
||||
# Поиск публикаций
|
||||
results = await search_service.search("машинное обучение", limit=10, offset=0)
|
||||
|
||||
# Поиск авторов
|
||||
authors = await search_service.search_authors("Иван Петров", limit=5)
|
||||
```
|
||||
|
||||
### Проверка статуса
|
||||
|
||||
```python
|
||||
# Информация о сервисе
|
||||
info = await search_service.info()
|
||||
|
||||
# Статус индекса
|
||||
status = await search_service.check_index_status()
|
||||
|
||||
# Проверка документов
|
||||
verification = await search_service.verify_docs(["1", "2", "3"])
|
||||
```
|
||||
|
||||
## 🐛 Отладка
|
||||
|
||||
### Логирование
|
||||
|
||||
```python
|
||||
# Включить debug логи
|
||||
import logging
|
||||
logging.getLogger("services.search").setLevel(logging.DEBUG)
|
||||
|
||||
# Проверить загрузку модели
|
||||
logger.info("🔍 SentenceTransformer model loaded successfully")
|
||||
```
|
||||
|
||||
### Диагностика
|
||||
|
||||
```python
|
||||
# Проверить количество проиндексированных документов
|
||||
info = await search_service.info()
|
||||
print(f"Documents: {info['muvera_info']['documents_count']}")
|
||||
|
||||
# Найти отсутствующие документы
|
||||
missing = await search_service.verify_docs(expected_doc_ids)
|
||||
print(f"Missing: {missing['missing']}")
|
||||
```
|
||||
|
||||
## 📈 Метрики производительности
|
||||
|
||||
### Типичные показатели
|
||||
|
||||
```
|
||||
📊 Производительность поиска:
|
||||
├── Поиск по 1000 документов: ~50ms
|
||||
├── Индексация 1 документа: ~100ms
|
||||
├── Batch индексация 100 документов: ~2s
|
||||
└── Память на 1000 документов: ~50MB
|
||||
```
|
||||
|
||||
### Оптимизация
|
||||
|
||||
1. **Batch обработка** - для массовых операций используйте `bulk_index()`
|
||||
2. **Тихий режим** - отключает детальное логирование
|
||||
3. **Кеширование** - результаты поиска кешируются в Redis
|
||||
4. **FDE сжатие** - уменьшает размер векторов в 2-3 раза
|
||||
|
||||
## 🔄 Миграция и обновления
|
||||
|
||||
### Переиндексация
|
||||
|
||||
```python
|
||||
# Полная переиндексация
|
||||
from main import initialize_search_index_with_data
|
||||
await initialize_search_index_with_data()
|
||||
```
|
||||
|
||||
### Обновление модели
|
||||
|
||||
1. Остановить сервис
|
||||
2. Обновить `sentence-transformers`
|
||||
3. Изменить модель в `MuveraWrapper.__init__()`
|
||||
4. Запустить переиндексацию
|
||||
|
||||
## 🔗 Связанные документы
|
||||
|
||||
- [API Documentation](api.md) - GraphQL эндпоинты
|
||||
- [Testing](testing.md) - Тестирование поиска
|
||||
- [Performance](performance.md) - Оптимизация производительности
|
||||
Reference in New Issue
Block a user