TRIE
Индекс « TRIE » в Milvus организует значения поля « VARCHAR » в виде префиксного дерева ( trie). Каждый символ в строке соответствует ребру в дереве, а общие префиксы хранятся только один раз. Такая структура позволяет быстро выполнять точный поиск строк и сопоставление префиксов без необходимости сканирования всех значений в поле.
Используйте индекс « TRIE », если вы часто выполняете запросы с:
Точное равенство строковых значений, например
category == "books"фильтрация по префиксам, например
name LIKE "abc%"
Поддерживаемые типы данных
VARCHARполя. Подробности см. в разделе «Строковое поле».
TRIE поддерживается только для полей типа « VARCHAR ». Чтобы проиндексировать строковое значение внутри поля типа « JSON », преобразуйте путь в тип « VARCHAR » и вместо этого используйте индекс NGRAM.
Принцип работы
Milvus реализует фильтрацию по префиксам ( TRIE ) в два этапа:
Создание индекса
Во время загрузки Milvus считывает каждое значение индексируемого поля.
Значения вставляются в трие: символы хранятся вдоль ребер, а каждый конечный узел фиксирует идентификаторы сущностей, у которых эта строка совпадает.
Готовое дерево сохраняется в качестве индекса.
Ускорение запросов
При проверке на равенство Milvus проходит по дереву символ за символом, чтобы добраться до узла с точным значением, и возвращает его идентификаторы сущностей.
При поиске по префиксу Milvus проходит до узла, соответствующего префиксу, и собирает идентификаторы сущностей в его поддереве.
Соответствующие идентификаторы сущностей передаются исполнителю запроса для окончательной сборки результата.
Для фильтров равенства и префикса затраты на поиск пропорциональны длине строки, а не количеству сущностей, что обеспечивает высокую скорость выполнения этих запросов в больших коллекциях.
Создание индекса TRIE
Вы можете создать индекс TRIE ( TRIE ) для поля типа « VARCHAR ». Никаких дополнительных параметров не требуется.
В примере ниже показано, как создать индекс TRIE ( TRIE ) для поля типа « VARCHAR »:
from pymilvus import MilvusClient
client = MilvusClient(uri="http://localhost:19530")
# Assume you have defined a VARCHAR field named "category" in your collection schema
# Prepare index parameters
index_params = client.prepare_index_params()
# Add TRIE index on the "category" field
index_params.add_index(
field_name="category", # Target VARCHAR field
index_type="TRIE", # Index type is TRIE
index_name="category_trie" # Optional, name your index
)
# Create the index on the collection
client.create_index(
collection_name="product_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.Collections;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("http://localhost:19530")
.build());
client.createIndex(CreateIndexReq.builder()
.collectionName("product_catalog")
.indexParams(Collections.singletonList(IndexParam.builder()
.fieldName("category")
.indexType(IndexParam.IndexType.TRIE)
.indexName("category_trie")
.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())
}
_, err = cli.CreateIndex(ctx, milvusclient.NewCreateIndexOption("product_catalog", "category", index.NewTrieIndex()).WithIndexName("category_trie"))
if err != nil {
log.Fatal("failed to create index: ", err.Error())
}
use milvus::v2::prelude::*;
let config = ConnectConfig::new().uri("http://localhost:19530");
let client = ClientV2::new(&config).await?;
client
.create_index(
CreateIndexRequest::builder()
.collection_name("product_catalog")
.index_param(
IndexParam::new()
.field_name("category")
.index_type(IndexType::Trie)
.index_name("category_trie"),
)
.build()?,
)
.await?;
#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->CreateIndex(milvus::CreateIndexRequest().WithCollectionName("product_catalog")
.AddIndex(milvus::IndexDesc("category", "category_trie", milvus::IndexType::TRIE)));
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: "product_catalog",
field_name: "category",
index_type: "TRIE",
index_name: "category_trie",
});
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": "product_catalog",
"indexParams": [
{
"fieldName": "category",
"indexName": "category_trie",
"indexType": "TRIE"
}
]
}'
# {
# "code": 0,
# "data": {}
# }
Запросы, ускоряемые с помощью TRIE
Индекс TRIE ускоряет выполнение следующих шаблонов фильтрации по полю VARCHAR:
Равенство
filter = 'category == "books"'Принадлежность
filter = 'category in ["books", "electronics"]'Совпадение префикса
filter = 'category LIKE "elec%"'Диапазон
filter = 'category >= "a" and category < "m"'При оценке диапазона может произойти обращение к нескольким индексированным строкам.
Сопоставление суффиксов, подстрок и общих шаблонов регулярных выражений ( LIKE ) также может выполняться по индексированным строкам, но для этого может потребоваться обращение к множеству различных значений. Если в вашей рабочей нагрузке преобладает сопоставление подстрок или регулярных выражений, рассмотрите возможность использования индекса FMINDEX или NGRAM.
Удаление индекса
Используйте метод drop_index() для удаления существующего индекса из коллекции.
В версии 2.6.3 или более ранних перед удалением скалярного индекса необходимо освободить коллекцию.
Начиная с версии 2.6.4 и более поздних, скалярный индекс можно удалить напрямую, как только он больше не нужен — предварительное освобождение коллекции не требуется.
client.drop_index(
collection_name="product_catalog", # Name of the collection
index_name="category_trie" # 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("product_catalog")
.indexName("category_trie")
.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("product_catalog", "category_trie"))
if err != nil {
log.Fatal("failed to drop index: ", err.Error())
}
use milvus::v2::prelude::*;
let config = ConnectConfig::new().uri("http://localhost:19530");
let client = ClientV2::new(&config).await?;
client
.drop_index(
DropIndexRequest::builder()
.collection_name("product_catalog")
.index_name("category_trie")
.build()?,
)
.await?;
#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("product_catalog")
.WithIndexName("category_trie"));
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: "product_catalog",
index_name: "category_trie",
});
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": "product_catalog",
"indexName": "category_trie"
}'
# {
# "code": 0,
# "data": {}
# }
Примечания по использованию
Типы полей: Работает только с полями типа «
VARCHAR». Дополнительную информацию о типах данных см. в разделе «Строковое поле».Параметры: Параметры индекса не требуются.
Сопоставление шаблонов: «
TRIE» работает быстрее всего при фильтрации по равенству и префиксу. Фильтры по диапазону поддерживаются, но могут затрагивать несколько индексированных строк. Шаблоны суффиксов, подстрок и общие шаблоны «LIKE» могут оцениваться, но для этого может потребоваться сканирование множества индексированных строк.
Рекомендации
Используйте «
TRIE», если в ваших фильтрах преобладают точные поиски или сопоставления по префиксу.Если ваша рабочая нагрузка основана на фильтрах подстрок (
LIKE "%abc%") или фильтрах с регулярными выражениями, используйте вместо этого FMINDEX для точного закреплённого сопоставления или NGRAM для сужения круга кандидатов.