• О компании Milvus
  • Начать работу
  • Понятия
  • Руководство пользователя
  • Импорт данных
  • Инструменты искусственного интеллекта
  • Руководство по администрированию
  • Инструменты
  • Интеграции
  • Учебные материалы
  • Часто задаваемые вопросы
  • API Reference

FMINDEX

Индекс « FMINDEX » в Milvus представляет собой индекс точных подстрок на уровне байтов для полей типа « VARCHAR ». Он обрабатывает запросы с закрепленными позициями ( LIKE ) с поиском по префиксу, инфиксу или суффиксу и возвращает точные совпадения без повторной проверки кандидатов.

Используйте индекс « FMINDEX », если вы часто применяете фильтры по подстрокам, например:

  • title LIKE "vector%" (префикс)

  • title LIKE "%database" (суффикс)

  • title LIKE "%vector database%" (вставка / подстрока)

В отличие от индекса « NGRAM », который сначала сужает круг кандидатов, а затем проводит повторную проверку, индекс « FMINDEX » может находить закрепленные шаблоны префиксов, суффиксов и инфиксов непосредственно из индекса.

Поддерживаемые типы данных

FMINDEX поддерживается только в полях типа « VARCHAR ». Он не поддерживает поля типа « JSON » или пути типа « JSON », приведенные к типу « VARCHAR ».

Принцип работы

FMINDEX Это полнотекстовый FM-индекс — сжатая структура, построенная на основе преобразования Берроуза-Уилера (BWT) из соединенных значений полей, вместе с массивом суффиксов, сгенерированным методом выборки, и вейвлет-деревом для запросов по рангу. Эта структура поддерживает обратный поиск: при заданном шаблоне Milvus проходит по нему от последнего символа к первому, чтобы найти точный диапазон сущностей, текст которых содержит данный шаблон.

Во время запроса Milvus использует индекс для:

  1. нахождения совпадений для закреплённого литерала, извлечённого из шаблона « LIKE ».

  2. Возврата точных идентификаторов сущностей для префиксных, суффиксных и инфиксных литералов без повторной проверки исходных значений.

Для шаблонов с несколькими несмежными литералами (общий « LIKE ») или сложных регулярных выражений функция « FMINDEX » может генерировать кандидаты, которые Milvus затем сверяет с исходными значениями.

Создание индекса FMINDEX

Вы можете создать индекс типа « FMINDEX » для поля типа « VARCHAR ». Оба параметра сборки являются необязательными; оставьте их незаданными, чтобы использовать значения по умолчанию сервера.

ПараметрОписаниеДопустимые значенияПо умолчанию
fm_sa_sample_rateЧастота выборки массива суффиксов. Обеспечивает баланс между размером индекса и задержкой при поиске; не влияет на запросы, использующие только подсчёт.Целое число от 4 до 2568
fm_block_bytesРазмерность блока каталога рангов в байтах. Более крупные блоки уменьшают размер резидентного каталога.8, 16, 32, 64 или 12864

В примере ниже показано, как создать индекс « FMINDEX » для поля « VARCHAR »:

from pymilvus import MilvusClient

client = MilvusClient(uri="http://localhost:19530")

# Assume you have defined a VARCHAR field named "text" in your collection schema

# Prepare index parameters
index_params = client.prepare_index_params()

# Add FMINDEX index on the "text" field
index_params.add_index(
    field_name="text",           # Target VARCHAR field
    index_type="FMINDEX",        # Index type is FMINDEX
    index_name="fmindex_index",  # Custom name for the index
    fm_sa_sample_rate=8,         # Optional: suffix-array sampling rate (4-256, default 8)
    fm_block_bytes=64            # Optional: block granularity in bytes (8/16/32/64/128, default 64)
)

# Create the index on the collection
client.create_index(
    collection_name="log_catalog",
    index_params=index_params
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.index.request.CreateIndexReq;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
        .uri("http://localhost:19530")
        .build());

Map<String, Object> params = new HashMap<>();
params.put("fm_sa_sample_rate", "8");
params.put("fm_block_bytes", "64");

client.createIndex(CreateIndexReq.builder()
        .collectionName("log_catalog")
        .indexParams(Arrays.asList(
                IndexParam.builder().fieldName("text").indexType(IndexParam.IndexType.FMINDEX)
                        .indexName("fmindex_index")
                        .extraParams(params)
                        .build()))
        .build());
import (
    "context"
    "log"

    "github.com/milvus-io/milvus/client/v3/index"
    "github.com/milvus-io/milvus/client/v3/milvusclient"
)

ctx := context.Background()

cli, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
    Address: "http://localhost:19530",
})

if err != nil {
    log.Fatal("failed to connect to milvus server: ", err.Error())
}

idx := index.NewFMIndex().WithSaSampleRate(8).WithBlockBytes(64)

_, err = cli.CreateIndex(ctx, milvusclient.NewCreateIndexOption("log_catalog", "text", idx).WithIndexName("fmindex_index"))

if err != nil {
    log.Fatal("failed to create index: ", err.Error())
}
#include <iostream>
#include "milvus/MilvusClientV2.h"

auto client = milvus::MilvusClientV2::Create();

auto status = client->Connect(milvus::ConnectParam("http://localhost:19530"));

if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

milvus::IndexDesc fmindex_index("text", "fmindex_index", milvus::IndexType::FMINDEX);
fmindex_index.AddExtraParam("fm_sa_sample_rate", "8");
fmindex_index.AddExtraParam("fm_block_bytes", "64");

status = client->CreateIndex(milvus::CreateIndexRequest().WithCollectionName("log_catalog")
        .AddIndex(fmindex_index));

if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}
import { MilvusClient } from "@zilliz/milvus2-sdk-node";

const client = new MilvusClient({ address: "http://localhost:19530" });

await client.createIndex({
    collection_name: "log_catalog",
    field_name: "text",
    index_type: "FMINDEX",
    index_name: "fmindex_index",
    params: { fm_sa_sample_rate: 8, fm_block_bytes: 64 },
});
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/indexes/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
    "collectionName": "log_catalog",
    "indexParams": [
        {
            "fieldName": "text",
            "indexName": "fmindex_index",
            "params": {
                "index_type": "FMINDEX",
                "fm_sa_sample_rate": 8,
                "fm_block_bytes": 64
            }
        }
    ]
}'

# {
#     "code": 0,
#     "data": {}
# }

Запросы, ускоряемые FMINDEX

FMINDEX ускоряет выполнение следующих шаблонов фильтрации по полю « VARCHAR ». Литералы с закреплённым префиксом, суффиксом и инфиксом точно сопоставляются с индексом; общие шаблоны « LIKE » и регулярных выражений генерируют кандидаты, которые Milvus сверяет с исходными значениями.

  • Совпадение префикса

    filter = 'text LIKE "vector%"'
    
  • Совпадение суффикса

    filter = 'text LIKE "%database"'
    
  • Совпадение инфикса / подстроки

    filter = 'text LIKE "%vector database%"'
    
  • Общий LIKE (варианты)

    filter = 'text LIKE "a%b_c"'
    
  • Регулярные выражения (варианты)

    filter = 'text =~ "error.*timeout"'
    

Дополнительные сведения о синтаксисе выражений фильтра см. в разделе «Сопоставление шаблонов».

Удаление индекса

Для удаления существующего индекса из коллекции используйте метод ` drop_index() `.

  • В версии 2.6.3 или более ранних версиях перед удалением скалярного индекса необходимо освободить коллекцию.

  • Начиная с версии 2.6.4 и более поздних версий, скалярный индекс можно удалить напрямую, как только он больше не нужен — предварительное освобождение коллекции не требуется.

client.drop_index(
    collection_name="log_catalog",   # Name of the collection
    index_name="fmindex_index"       # Name of the index to drop
)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.index.request.DropIndexReq;

MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
        .uri("http://localhost:19530")
        .build());

client.dropIndex(DropIndexReq.builder()
        .collectionName("log_catalog")
        .indexName("fmindex_index")
        .build());
import (
    "context"
    "log"

    "github.com/milvus-io/milvus/client/v3/milvusclient"
)

ctx := context.Background()

cli, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
    Address: "http://localhost:19530",
})

if err != nil {
    log.Fatal("failed to connect to milvus server: ", err.Error())
}

err = cli.DropIndex(ctx, milvusclient.NewDropIndexOption("log_catalog", "fmindex_index"))

if err != nil {
    log.Fatal("failed to drop index: ", err.Error())
}
#include <iostream>
#include "milvus/MilvusClientV2.h"

auto client = milvus::MilvusClientV2::Create();

auto status = client->Connect(milvus::ConnectParam("http://localhost:19530"));

if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}

status = client->DropIndex(milvus::DropIndexRequest()
        .WithCollectionName("log_catalog")
        .WithIndexName("fmindex_index"));

if (!status.IsOk()) {
    std::cout << status.Message() << std::endl;
}
import { MilvusClient } from "@zilliz/milvus2-sdk-node";

const client = new MilvusClient({ address: "http://localhost:19530" });

await client.dropIndex({
    collection_name: "log_catalog",
    index_name: "fmindex_index",
});
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/indexes/drop" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
    "collectionName": "log_catalog",
    "indexName": "fmindex_index"
}'

# {
#     "code": 0,
#     "data": {}
# }

Примечания по использованию

  • Типы полей: Работает только с полями типа « VARCHAR ». Дополнительную информацию о типах данных см. в разделе «Строковое поле».

  • Совместимость версий: для индекса « FMINDEX » требуется версия механизма скалярных индексов 5 или более поздняя.

  • Доступность SDK: SDK Rust v2 пока не включает тип индекса « FMINDEX ».

  • Точное сопоставление: литералы LIKE с закрепленным префиксом, суффиксом и инфиксом возвращают точные совпадения без повторной проверки кандидатов.

  • Кандидаты: общие шаблоны « LIKE » и регулярных выражений могут генерировать кандидаты, которые Milvus сверяет с исходными значениями. Если шаблон обеспечивает незначительную полезную фильтрацию или его разрешение слишком ресурсоемко, Milvus может вместо этого выполнить сканирование поля.

  • Неизменяемость: значения fm_sa_sample_rate и fm_block_bytes нельзя изменять на месте — для их корректировки необходимо перестроить индекс.

Рекомендации

  • Используйте параметр FMINDEX для точного поиска подстрок в длинных полях VARCHAR, особенно если повторная проверка кандидатов NGRAM требует значительных ресурсов.

  • Для большинства рабочих нагрузок оставляйте значение fm_block_bytes на уровне по умолчанию (64); увеличьте его, чтобы уменьшить размер резидентного каталога при нехватке памяти.

  • Уменьшение значения fm_sa_sample_rate снижает задержку при выполнении команды locate за счёт увеличения размера индекса; увеличьте его, чтобы уменьшить размер индекса, если запросы в основном сводятся к подсчёту количества вхождений.

ПереведеноDeepL

Попробуйте Managed Milvus бесплатно

Zilliz Cloud работает без проблем, поддерживается Milvus и в 10 раз быстрее.

Начать
Обратная связь

Была ли эта страница полезной?