---
title: "Векторные базы данных"
url: "https://romankryvolapov.com/ru/vector-databases/"
description: "Векторные базы на практике: чем отличаются Milvus, Qdrant и Weaviate, как считаются эмбеддинги, работают индексы HNSW и поиск по близости."
language: ru
updated: 2026-01-21
---
Машинное обучение и особенно нейросети позволяют преобразовывать "неструктурированные данные" в векторы фиксированной длины (чаще всего float32), которые сохраняют семантику исходного объекта. Например, два похожих текста будут иметь близкие векторы (малая евклидова дистанция или высокая косинусная близость).

**Векторные базы данных (vector databases):**\
это специализированные хранилища, предназначенные для эффективного поиска и сопоставления векторов (обычно — эмбеддингов), которые представляют объекты вроде текста, изображений, аудио или видео в числовом виде.

## Что обычно хранится в векторной базе {#Что-обычно-хранится-в-векторной-базе}

| Компонент | Что это | Пример |
| --- | --- | --- |
| **ID** | Уникальный идентификатор записи | "doc-001" или 123 |
| **Вектор** | Числовой список, представляющий объект | \[0.12, -0.56, 0.44, …, -0.03\] (обычно float32) |
| **Документ** | Исходный текст или файл (опционально) | "Как дела?" |
| **Метаданные** | Доп. поля для фильтрации, тегов, контекста | {"language": "ru", "user": "petya", "tags": \["faq"\]} |

## Популярные векторные базы {#Популярные-векторные-базы}

| **Название** | **Разработчик** | **Индексирование** | **Метрики** | **Плюсы** | **Минусы** |
| --- | --- | --- | --- | --- | --- |
| **Milvus** | Zilliz | IVF_FLAT, IVF_SQ8, IVF_PQ, HNSW, ANNOY, Flat | L2, IP, Cosine, Jaccard, Hamming | Масштабируемость (миллиарды точек)<br>Много индексов<br>gRPC/REST | Требует Docker или Standalone<br>Сложнее развернуть |
| **Qdrant** | Qdrant (на Rust) | HNSW (модифицированный), Flat | Cosine, Dot, Euclidean (L2) | Быстрый, Rust-движок<br>Лёгкая установка<br>Фильтрация по метаданным | Пока меньше индексов<br>Нет встроенной кластеризации |
| **Weaviate** | Semi.technologies | HNSW + Text (Hybrid Search) | Cosine, Dot, Euclidean | Гибридный поиск (BM25 + векторный)<br>GraphQL API<br>Автоинжекция данных | Требует больше памяти<br>GraphQL не всегда удобен |
| **Chroma** | Chroma org | Flat (точный), HNSW (в roadmap/частично) | Cosine | Очень простая установка<br>Идеален для RAG и локального запуска | Только Flat (пока)<br>Нет фильтрации по метаданным (частично есть) |
| **FAISS** | Facebook/Meta | Flat, IVF, PQ, OPQ, HNSW, LSH | L2, Dot, Cosine (через нормализацию) | Очень гибкий<br>GPU-поддержка<br>Лучшая производительность на CPU/GPU | Это библиотека, не сервер<br>Нужна ручная настройка и кодирование |
| **OpenSearch** | Amazon | HNSW, Faiss backend, ANN native plugin | L2, Dot, Cosine | Гибридный поиск (BM25 + ANN)<br>Интеграция с текстом<br>Elasticsearch-совместим | Сложная настройка ANN<br>Высокие требования к памяти |

## Преобразование данных в векторы (Embedding) {#Преобразование-данных-в-векторы-Embedding}

Например, текст "Как дела?" может быть преобразован в вектор из 384 значений

```kotlin
[0.12, -0.56, 0.44, ..., -0.03]
```

Для этого используются специализированные embedding модели, такие как:

| **Название** | **Что кодирует и как работает** | **Преимущества** |
| --- | --- | --- |
| **all-MiniLM-L6-v2** | Лёгкая и быстрая модель на базе Transformer<br>Кодирует фразы, вопросы, абзацы | Компактная (~80MB)<br>Поддержка в sentence-transformers<br>Работает «из коробки» |
| **text-embedding-ada-002**<br>(OpenAI) | Коммерческая модель от OpenAI<br>Требует API-ключ<br>Кодирует любые тексты | Высокое качество эмбеддингов<br>Поддержка разных языков<br>Отлично подходит для RAG |
| **bge-small-en** | Современная модель от BAAI<br>Поддерживает шаблоны: "query:...", "passage:..." | Высокая точность<br>Поддержка многоязычия (в M3E)<br>Отлична для Qdrant, LangChain |
| **e5-base / e5-large** | Универсальные модели от FlagAI<br>Подходят для поиска, кластеризации, QA | Лучшие показатели на MTEB<br>Поддержка многоязычных задач<br>Работают без fine-tune |
| **Instructor-XL** | Кодирует текст с учётом задачи<br>Использует инструкции в стиле: "Represent the ... for ..." | Повышенная точность<br>Подходит для task-aware embedding<br>Отлично для RAG/FAQ |
| **mpnet-base-v2** | От Microsoft<br>Контекстно-чувствительная модель<br>Хороша для похожих фраз | Хороший баланс точности и скорости<br>Подходит для paraphrase и general search |
| **LaBSE** | От Google<br>Многоязычная модель<br>Лучше всего с короткими предложениями | Поддержка 100+ языков<br>Отличный выбор для кросс-языкового поиска |

Типичные размеры векторов (длины эмбеддингов) разных моделей:

| **Модель** | **Длина вектора** |
| --- | --- |
| all-MiniLM-L6-v2 | 384 |
| text-embedding-ada-002 (OpenAI) | 1536 |
| bge-small-en | 384 |
| bge-base-en | 768 |
| bge-large-en | 1024 |
| e5-small-v2 | 384 |
| e5-base-v2 | 768 |
| e5-large-v2 | 1024 |
| mpnet-base-v2 | 768 |
| LaBSE | 768 |
| Instructor-XL | 768 или 1024 |

## Индексирование векторов {#Индексирование-векторов}

Вектора, соответствующие объектам, индексируются, чтобы потом можно было быстро по входящему вектору искать максимально близкие из сохраненных в базе.\
Способы индексации векторов:

**Виды индексов:**

| **Название** | **Как работает** | **Преимущества** | **Недостатки** |
| --- | --- | --- | --- |
| **Flat** | Перебирает все векторы вручную | Самый точный поиск<br>Простая реализация<br>Идеально для отладки и небольших наборов | Очень медленно при большом объёме<br>Требует много вычислений<br>Не масштабируется |
| **HNSW** | Поиск по сети похожих векторов (начиная с "центров") | Очень быстрый<br>Высокая точность<br>Подходит для больших баз | Требует много памяти<br>Долгое построение индекса<br>Сложен в параметризации |
| **IVF** | Делит векторы на группы (кластеры), ищет только в них | Быстрее, чем Flat<br>Гибкая настройка (nprobe)<br>Хорошо масштабируется | Может пропустить похожие векторы<br>Требует предварительного обучения |
| **PQ** | Заменяет части вектора короткими кодами | Сильно экономит память<br>Быстрый поиск по таблице<br>Идеален для больших наборов | Потеря точности<br>Требуется обучение (codebook)<br>Не для задач с высокой точностью |
| **OPQ** | Улучшенная версия PQ — сначала "поправляет" вектор | Выше точность, чем у PQ<br>Хорошо работает в FAISS, Milvus<br>Комбинируется с IVF | Сложнее в обучении<br>Всё ещё приближённый метод |
| **Annoy** | Строит много случайных деревьев, ищет по ним | Прост в использовании<br>Мало зависит от ресурсов<br>Подходит для CPU и мобильных | Менее точный, чем HNSW<br>Долгое построение индекса<br>Нельзя обновить после построения |

## Поиск ближайших векторов (Similarity Search) {#Поиск-ближайших-векторов-Similarity-Search}

Когда пользователь вводит запрос, он преобразуется в вектор, и база выполняет поиск ближайших соседей (KNN) по выбранной метрике.

**Виды метрик:**

| **Название метрики** | **Как работает** | **Преимущества** | **Недостатки** |
| --- | --- | --- | --- |
| **Cosine Similarity** | Сравниваем угол между векторами. Чем ближе угол к 0°, тем больше сходство. | Учитывает только направление<br>Хорошо работает с текстами и эмбеддингами<br>Не зависит от длины вектора | Не учитывает масштаб (длину)<br>Не подходит, если длина вектора важна |
| **Euclidean (L2)** | Меряем «линейное» расстояние между точками. Ближе — значит похожее. | Простая и интуитивно понятная<br>Подходит для координат, изображений | Не нормирует вектора (масштаб влияет)<br>Не всегда хорошо для текстов |
| **Inner Product (Dot Product)** | Складываем соответствующие координаты. Чем больше сумма, тем выше сходство. | Очень быстро считается<br>Хорошо работает с ненормализованными векторами | Чувствителен к длине вектора<br>Могут быть трудно интерпретируемые значения |
| **Manhattan (L1)** | Сумма модулей разностей по каждой координате — как по клеткам на сетке. | Устойчив к выбросам<br>Лучше работает с разреженными векторами | Реже используется<br>Хуже работает с плотными векторами |
| **Hamming Distance** | Считаем количество битов, в которых отличаются два бинарных вектора. | Очень быстрый для бинарных данных<br>Подходит для fingerprint и хэшей | Работает только с бинарными векторами<br>Не применим к float |
| **Jaccard Similarity** | Отношение пересечения к объединению множеств или бинарных векторов. | Идеален для тегов и бинарных признаков<br>Понятная метрика | Только для бинарных векторов<br>Не работает с float-векторами |
| **Tanimoto** | Обобщённая Jaccard-метрика, применимая и к float-векторам. | Подходит для химических структур, fingerprint<br>Работает и с бинарными, и с вещественными | Редко используется<br>Ограниченная поддержка в библиотеках |

## Пример работы с векторной базой {#Пример-работы-с-векторной-базой}

В примере CRUD операций будем использовать Python, базу Milvus, embedding модель e5‑base

```python
from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection
from pymilvus.model.dense import SentenceTransformerEmbeddingFunction

# 1. Подключение к Milvus (по умолчанию localhost:19530)
connections.connect("default", host="localhost", port="19530")

# 2. Инициализация функции эмбеддинга с моделью e5-base-v2
# Эта модель требует:
# - Префикс "passage: " для документов
# - Префикс "query: " для поисковых запросов
ef = SentenceTransformerEmbeddingFunction("intfloat/e5-base-v2")

# 3. Определение схемы коллекции:
# - "id" — целочисленный идентификатор (первичный ключ)
# - "text" — исходный текст документа (строка)
# - "emb" — эмбеддинг-вектор размерности 768
fields = [
    FieldSchema(name="id", dtype=DataType.INT64, is_primary=True, auto_id=False),
    FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=512),
    FieldSchema(name="emb", dtype=DataType.FLOAT_VECTOR, dim=768)
]
schema = CollectionSchema(fields, description="Коллекция с эмбеддингами от e5-base-v2")

# 4. Создание коллекции в Milvus с заданной схемой
collection = Collection("e5_collection", schema)

# 5. Подготовка и вставка документов
# Важно: перед подачей в модель нужно добавить префикс "passage: "
raw_docs = ["Hello world", "Milvus vector database", "Semantic search with e5 model"]
docs = [f"passage: {d}" for d in raw_docs]  # добавляем префикс
ids = [1, 2, 3]

# Вычисляем эмбеддинги для документов используя e5‑base
embs = ef.encode_documents(docs)

# Вставляем в коллекцию:
# - идентификаторы
# - исходные (чистые) тексты без префиксов
# - эмбеддинги
collection.insert([ids, raw_docs, embs])

# 6. Создание индекса по полю "emb" для ускорения поиска
collection.create_index(
    field_name="emb",
    index_params={
        # тип индекса
        "index_type": "IVF_FLAT",

        # параметр разбиения на кластеры
        "params": {"nlist": 128},

        # метрика расстояния (евклидово расстояние)
        "metric_type": "L2"
    }
)

# 7. Загрузка коллекции в оперативную память
# Без этого поиск работать не будет
collection.load()

# 8. Поисковый запрос
# Аналогично — используем префикс "query: " перед текстом запроса
query_docs = ["query: vector database"]
q_emb = ef.encode_queries(query_docs)

# Выполняем семантический поиск по эмбеддингам
results = collection.search(
    # эмбеддинг поискового запроса
    data=q_emb,

    # поле, по которому осуществляется поиск
    anns_field="emb",

    # параметры поиска
    param={"metric_type": "L2", "params": {"nprobe": 10}},

    # количество ближайших соседей
    limit=2,

    # дополнительные поля, которые нужно вернуть
    output_fields=["text"]
)

# 9. Выводим результаты поиска
for i, hits in enumerate(results):
    print(f"Результаты для запроса: '{query_docs[i]}'")
    if not hits:
        print("Ничего не найдено")
        continue
    for rank, hit in enumerate(hits, start=1):
        print(f"  {rank}:")
        print(f"    ID: {hit.id}")
        print(f"    Текст: {hit.entity.get('text')}")
        print(f"    Расстояние: {hit.distance:.4f}")

# Результаты для запроса: 'query: vector database'
#  1:
#    ID: 2
#    Текст: Milvus vector database
#    Расстояние: 2.8374
#  2:
#    ID: 3
#    Текст: Semantic search with e5 model
#    Расстояние: 5.4931

# 10. Удаление документа по ID
# В данном случае удаляется документ с id = 1
collection.delete(expr="id in [1]")

# 11. Удаление всей коллекции (если больше не нужна)
collection.drop()
```

[Copyright: Roman Kryvolapov](https://t.me/RomanKryvolapov)
