← Назад к вопросам

Какие знаешь инструменты поиска по словам?

2.0 Middle🔥 201 комментариев
#Python Core

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Инструменты поиска по словам (Full-Text Search)

Основные инструменты поиска

Для реализации полнотекстового поиска (full-text search) есть несколько популярных решений с разными характеристиками:

1. Elasticsearch — самый популярный

Elasticsearch — это распределённая поисковая система на основе Lucene. Стандарт для полнотекстового поиска:

from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulk

# Подключение
es = Elasticsearch(['http://localhost:9200'])

# Создание индекса с анализатором
es.indices.create(index='articles', body={
    'settings': {
        'analysis': {
            'analyzer': {
                'russian_analyzer': {
                    'type': 'standard',
                    'stopwords': '_russian_'
                }
            }
        }
    },
    'mappings': {
        'properties': {
            'title': {'type': 'text', 'analyzer': 'russian_analyzer'},
            'content': {'type': 'text', 'analyzer': 'russian_analyzer'},
            'tags': {'type': 'keyword'},
            'created_at': {'type': 'date'}
        }
    }
})

# Индексирование документов
documents = [
    {'_index': 'articles', '_id': 1, 'title': 'Python для начинающих', 'content': 'Изучение Python', 'tags': ['python', 'tutorial']},
    {'_index': 'articles', '_id': 2, 'title': 'Django веб-фреймворк', 'content': 'Создание веб-приложений', 'tags': ['django', 'web']},
]
bulk(es, documents)

# Поиск по словам
query = {
    'query': {
        'multi_match': {
            'query': 'Python Django',  # Поиск по нескольким полям
            'fields': ['title^2', 'content'],  # title важнее (boost=2)
            'operator': 'and'  # Все слова должны совпадать
        }
    },
    'highlight': {
        'fields': {
            'title': {},
            'content': {}
        }
    }
}

results = es.search(index='articles', body=query)
for hit in results['hits']['hits']:
    print(f'Score: {hit["_score"]}')
    print(f'Title: {hit["_source"]["title"]}')
    if 'highlight' in hit:
        print(f'Highlighted: {hit["highlight"]}')

# Фильтрация с поиском
query_filtered = {
    'query': {
        'bool': {
            'must': [
                {'multi_match': {'query': 'Python', 'fields': ['title', 'content']}}
            ],
            'filter': [
                {'term': {'tags': 'python'}},
                {'range': {'created_at': {'gte': '2024-01-01'}}}
            ]
        }
    }
}

# Faceted search (получить категории)
faceted_query = {
    'query': {'match_all': {}},
    'aggs': {
        'tags': {
            'terms': {'field': 'tags', 'size': 10}
        },
        'by_date': {
            'date_histogram': {'field': 'created_at', 'interval': 'month'}
        }
    }
}

Преимущества:

  • Очень быстро
  • Развитая экосистема
  • Масштабируемость
  • Faceting, suggest, autocomplete
  • RESTful API

Недостатки:

  • Требует отдельного сервера
  • Сложная настройка
  • Память и CPU потребление

2. PostgreSQL Full Text Search

PostgreSQL встроенный полнотекстовый поиск — простое решение для средних объёмов:

import psycopg2
from datetime import datetime

conn = psycopg2.connect(
    host='localhost',
    database='myapp',
    user='postgres'
)
cursor = conn.cursor()

# Создание таблицы с полнотекстовым индексом
cursor.execute('''
    CREATE TABLE IF NOT EXISTS articles (
        id SERIAL PRIMARY KEY,
        title TEXT NOT NULL,
        content TEXT NOT NULL,
        search_vector tsvector GENERATED ALWAYS AS (
            to_tsvector('russian', title) || to_tsvector('russian', content)
        ) STORED
    );
    
    -- Индекс для быстрого поиска
    CREATE INDEX IF NOT EXISTS articles_search_idx ON articles USING GIN (search_vector);
''')

# Вставка данных
cursor.execute('''
    INSERT INTO articles (title, content) VALUES
    (%s, %s)
''', ('Python для начинающих', 'Изучение Python и её основ'))
conn.commit()

# Поиск по словам
search_query = 'Python'
cursor.execute(f'''
    SELECT id, title, 
           ts_rank(search_vector, query) as relevance,
           ts_headline('russian', content, query, 'HighlightAll=true') as snippet
    FROM articles,
         plainto_tsquery('russian', %s) as query
    WHERE search_vector @@ query
    ORDER BY relevance DESC
    LIMIT 10
''', (search_query,))

for row in cursor.fetchall():
    print(f'ID: {row[0]}')
    print(f'Title: {row[1]}')
    print(f'Relevance: {row[2]}')
    print(f'Snippet: {row[3]}')

# Поиск с повышением релевантности
cursor.execute('''
    SELECT id, title,
           ts_rank(search_vector, query) * 
           CASE WHEN title @@ query THEN 1.5 ELSE 1 END as relevance
    FROM articles,
         plainto_tsquery('russian', %s) as query
    WHERE search_vector @@ query
    ORDER BY relevance DESC
''', ('Python',))

conn.close()

Преимущества:

  • Встроено в PostgreSQL
  • Нет дополнительной инфраструктуры
  • Достаточно быстро
  • Хорошо для русского языка

Недостатки:

  • Медленнее Elasticsearch
  • Ограниченные возможности (нет fuzzy, но есть)
  • Нельзя масштабировать за пределы одного сервера

3. Apache Solr

Apache Solr — альтернатива Elasticsearch, также на основе Lucene:

import requests
import json

solr_url = 'http://localhost:8983/solr'

# Индексирование документа
doc = {
    'id': '1',
    'title': 'Python для начинающих',
    'content': 'Изучение Python',
    'category': 'python'
}

response = requests.post(
    f'{solr_url}/articles/update?commit=true',
    json={'add': {'doc': doc}},
    headers={'Content-Type': 'application/json'}
)

# Поиск
params = {
    'q': 'title:Python',  # Поиск в поле title
    'rows': 10,
    'sort': 'score desc',
    'hl': 'true',  # Highlighting
    'hl.fl': 'title,content'  # Какие поля выделять
}

response = requests.get(f'{solr_url}/articles/select', params=params)
results = response.json()

for doc in results['response']['docs']:
    print(f'Score: {doc.get("score")}')
    print(f'Title: {doc["title"]}')

Преимущества:

  • Похож на Elasticsearch
  • Стабилен
  • Хорошо для энтерпрайза

Недостатки:

  • Менее популярен чем Elasticsearch
  • Медленнее индексирует

4. meilisearch — быстрый и простой

MeiliSearch — современный поисковик с акцентом на простоту и скорость:

import meilisearch

# Подключение
client = meilisearch.Client('http://localhost:7700', 'your-master-key')

# Создание индекса
index = client.create_index('articles', {'primaryKey': 'id'})

# Индексирование
documents = [
    {'id': 1, 'title': 'Python для начинающих', 'content': 'Изучение'},
    {'id': 2, 'title': 'Django веб-фреймворк', 'content': 'Создание сайтов'},
]
index.add_documents(documents)

# Поиск
results = index.search('Python')
print(f'Found {results["nbHits"]} results')
for hit in results['hits']:
    print(f'Title: {hit["title"]}')

# Advanced search
advanced = index.search(
    'Python',
    {
        'limit': 10,
        'offset': 0,
        'facets': ['category'],  # Фасеты
        'attributesToHighlight': ['title', 'content'],
    }
)

Преимущества:

  • Очень просто использовать
  • Быстро работает
  • Автоматический typo tolerant
  • REST API

Недостатки:

  • Менее гибкий чем Elasticsearch
  • Меньше возможностей

5. SQLite с FTS5

SQLite FTS5 — встроенный полнотекстовый поиск для SQLite:

import sqlite3

conn = sqlite3.connect(':memory:')
cursor = conn.cursor()

# Создание таблицы с FTS5
cursor.execute('''
    CREATE VIRTUAL TABLE articles USING fts5(
        title,
        content
    );
''')

# Индексирование
cursor.execute("INSERT INTO articles VALUES (?, ?)",
    ('Python для начинающих', 'Изучение Python')
)
cursor.execute("INSERT INTO articles VALUES (?, ?)",
    ('Django веб-фреймворк', 'Создание веб-приложений')
)

# Поиск
cursor.execute('''
    SELECT title, rank
    FROM articles
    WHERE articles MATCH 'Python'
    ORDER BY rank
''')

for title, rank in cursor.fetchall():
    print(f'Title: {title}, Relevance: {rank}')

# Фраза и AND/OR
cursor.execute('''
    SELECT title
    FROM articles
    WHERE articles MATCH 'Python AND web'
''')

conn.close()

Преимущества:

  • Встроено в SQLite
  • Нет дополнительных сервисов
  • Достаточно быстро

Недостатки:

  • Медленнее чем специализированные
  • Ограниченные возможности

Сравнение инструментов

ИнструментСкоростьПростотаМасштабируемостьКогда использовать
Elasticsearch⚡⚡⚡⭐⭐⭐⭐⭐Большие проекты, high-load
PostgreSQL FTS⚡⚡⭐⭐⭐⭐⭐Средние объёмы, простые требования
Apache Solr⚡⚡⭐⭐⭐⭐⭐⭐Enterprise, стабильность
MeiliSearch⚡⚡⭐⭐⭐⭐⭐⭐Стартапы, simple search
SQLite FTS5⭐⭐⭐Маленькие приложения

Best Practices

Используй Elasticsearch для production с высокими требованиями ✅ Используй PostgreSQL FTS для среднего масштаба ✅ Используй MeiliSearch для быстрого прототипирования ✅ Индексируй в фоне через Celery/RQ ✅ Синхронизируй данные между основной БД и поисковиком ✅ Используй boost для важных полей (title важнее content) ✅ Кэшируй популярные запросы в Redis

Архитектура поиска

    PostgreSQL (основная БД)
         ↓
    Celery Task (индексирование)
         ↓
    Elasticsearch (индекс поиска)
         ↓
    REST API (поиск)
         ↓
   Frontend (результаты с highlight)

Выбор инструмента зависит от масштаба, требований к скорости и сложности логики поиска.

Какие знаешь инструменты поиска по словам? | PrepBro