TRIE
Milvus 中的TRIE 索引将VARCHAR 字段的值组织成一个前缀树(Trie)。字符串中的每个字符都对应树中的一条边,且相同的前缀仅存储一次。这种结构使得精确字符串查找和前缀匹配速度很快,无需扫描字段中的每个值。
如果您经常执行以下类型的查询,请使用TRIE 索引:
对字符串值进行精确相等比较,例如
category == "books"前缀过滤,例如
name LIKE "abc%"
支持的数据类型
VARCHAR字段。有关详细信息,请参阅“字符串字段”。
TRIE 仅在VARCHAR 字段上受支持。若要对JSON 字段中的字符串值进行索引,请将路径转换为VARCHAR ,并改用NGRAM索引。
工作原理
Milvus分两阶段实现TRIE :
构建索引
在数据摄入过程中,Milvus 会读取索引字段的每个值。
这些值会被插入到一个三叉树中:字符存储在边上,每个终端节点记录共享该字符串的实体 ID。
生成的树结构将作为索引持久化存储。
加速查询
对于相等性查询,Milvus 会逐个字符遍历树,找到与精确值对应的节点,并返回其实体 ID。
对于前缀查询,Milvus 会逐个字符遍历树,找到与前缀完全匹配的节点,并返回该节点的实体 ID。
匹配的实体 ID 会被传递给查询执行器,以进行最终结果的组装。
对于相等性和前缀过滤器,查找成本与字符串长度成正比,而不是与实体数量成正比,这使得这些查询在大型Collection中仍然很快。
创建 TRIE 索引
您可以在VARCHAR 字段上创建TRIE 索引。无需任何额外参数。
以下示例演示了如何在VARCHAR 字段上创建TRIE 索引:
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() 方法从 Collection 中删除现有索引。
在v2.6.3及更早版本中,在删除标量索引之前,必须先释放 Collection。
从v2.6.4及更高版本开始,一旦不再需要标量索引,即可直接删除,无需先释放 Collection。
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模式均可进行评估,但可能需要扫描大量已索引的字符串。