• 關於 Milvus
  • 開始使用
  • 概念
  • 使用者指南
  • 資料匯入
  • AI 工具
  • 管理指南
  • 工具
  • 整合功能
  • 教學指南
  • 常見問題
  • API Reference

FMINDEX

Milvus 中的FMINDEX 索引是針對VARCHAR 欄位的精確位元組級子字串索引。它可處理帶有前綴、中綴或後綴匹配的錨定LIKE 查詢,並在無需重新檢查候選結果的情況下,直接返回精確匹配結果。

FMINDEX 若您經常執行子字串篩選,例如:

  • title LIKE "vector%" (前綴)

  • title LIKE "%database" (後綴)

  • title LIKE "%vector database%" (中綴 / 子字串)

與NGRAM 不同,後者會先縮小候選結果範圍再進行重新檢查,而FMINDEX 則能直接從索引中解析錨定前綴、後綴和插入模式。

支援的資料類型

  • VARCHAR 欄位。詳細資訊請參閱「字串欄位」。

FMINDEX 僅在VARCHAR 欄位上受支援。它不支援JSON 欄位,也不支援鑄造為VARCHAR 的JSON 路徑。

運作原理

FMINDEX 這是一種全文 FM 索引,其結構由串接的欄位值經 Burrows-Wheeler 變換 (BWT) 後所建構的壓縮結構組成,並搭配用於秩查詢的採樣後綴陣列和小波樹。 此佈局支援向後搜尋:給定一個模式,Milvus 會從該模式的最後一個字元向其第一個字元遍歷,以找出其文字中包含該模式的實體的精確範圍。

在查詢時,Milvus 會利用此索引來:

  1. 定位從LIKE 模式中提取的錨定字面量之匹配結果。

  2. 針對前綴、後綴及中綴字面量,直接返回確切的實體 ID,無需重新檢查原始值。

對於包含多個非相鄰字面量(一般LIKE )或複雜正規表達式的模式,FMINDEX 可能會產生候選結果,隨後 Milvus 會將其與原始值進行比對驗證。

建立 FMINDEX 索引

您可以在VARCHAR 欄位上建立FMINDEX 索引。這兩項建置參數皆為可選;若未設定,則採用伺服器的預設值。

參數說明允許的值預設值
fm_sa_sample_rate後綴陣列的採樣率。此參數會在索引大小與定位延遲之間取得平衡;不影響僅計數的查詢。4 至 256 之間的整數8
fm_block_bytes按位元組計算的排名目錄區塊粒度。較大的區塊可縮小駐留目錄的大小。8、16、32、64 或 12864

以下範例展示如何在VARCHAR 欄位上建立FMINDEX 索引:

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() ` 方法從集合中移除現有的索引。

  • 在v2.6.3或更早版本中,您必須先釋放集合,才能刪除標量索引。

  • 自v2.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 可用性:Rust v2 SDK 目前尚未包含FMINDEX 索引類型。

  • 精確匹配:帶錨點的前綴、後綴及中綴LIKE 字面量會返回精確匹配結果,且無需重新檢查候選項。

  • 候選項:一般LIKE 與正規表達式模式可能會產生候選項,Milvus會將其與原始值進行比對驗證。當模式提供的篩選效果有限,或解析成本過高時,Milvus可能會改為掃描該欄位。

  • 不可變性: fm_sa_sample_rate 和fm_block_bytes 無法就地修改——需重建索引才能調整它們。

最佳實務

  • 針對長串的VARCHAR 欄位進行精確子字串搜尋時,請使用FMINDEX ,特別是在NGRAM 候選結果重新檢查的開銷較高時。

  • 對於大多數工作負載,請將fm_block_bytes 維持在預設值 64;當記憶體不足時,可增加此數值以縮小駐留目錄。

  • 降低fm_sa_sample_rate 可改善 locate 的延遲,但代價是索引會變大;當查詢多為僅計數時,可提高此值以縮小索引大小。

翻譯者DeepL

免費嘗試托管的 Milvus

Zilliz Cloud 無縫接入,由 Milvus 提供動力,速度提升 10 倍。

開始使用
反饋

這個頁面有幫助嗎?