🚀 免費嘗試 Zilliz Cloud,完全托管的 Milvus,體驗速度提升 10 倍!立即嘗試

milvus-logo
LFAI
主頁
  • 使用者指南
  • Home
  • Docs
  • 使用者指南

  • 搜尋與重新排名

  • 使用磁碟分割金鑰

使用分區鑰匙

分區關鍵是基於分區的搜尋最佳化解決方案。透過指定特定的標量欄位為分區關鍵 (Partition Key),並在搜尋過程中根據分區關鍵指定篩選條件,可將搜尋範圍縮小為數個分區,進而提高搜尋效率。本文將介紹如何使用分區關鍵及相關注意事項。

概述

在 Milvus 中,您可以使用分區來執行資料分隔,並透過限制搜尋範圍到特定的分區來改善搜尋效能。如果您選擇手動管理分區,您可以在一個集合中建立最多 1,024 個分區,並根據特定規則插入實體到這些分區中,這樣您就可以通過限制在特定數量的分區中進行搜索來縮窄搜索範圍。

Milvus 引入了分區鑰匙,讓您在資料分隔中重複使用分區,以克服在集合中建立分區數量的限制。當建立一個資料集時,您可以使用一個標量欄位作為分割鍵。一旦集合準備就緒,Milvus 會在集合內建立指定數量的分區,每個分區對應於分區鍵值的範圍。當接收到插入的實體時,Milvus 會根據它們的 Partition Key 值將它們儲存到不同的分區中。

Partition v.s. Partition Key 分區對分區鑰

下圖說明 Milvus 如何在有或沒有啟用「分區鍵」功能的情況下,處理資料集中的搜尋要求。

  • 如果關閉了分割區金鑰,Milvus 會在資料集中搜尋與查詢向量最相似的實體。如果您知道哪個分區包含最相關的結果,就可以縮小搜尋範圍。

  • 如果啟用了分割區金鑰,Milvus 會根據搜尋篩選器中指定的分割區金鑰值來決定搜尋範圍,並只掃描分割區內符合條件的實體。

With or Without Partition Key 使用或不使用分割區金鑰

使用分割區金鑰

要使用分區鍵值,您需要

  • 設定分割區金鑰。

  • 設定要建立的分割區數量 (選用),以及

  • 根據分割區金鑰建立篩選條件。

設定分割區金鑰

若要指定標量欄位為分割區金鑰,您需要在新增標量欄位時,將其is_partition_key 屬性設定為true

from pymilvus import (
    MilvusClient, DataType
)

client = MilvusClient(
    uri="http://localhost:19530",
    token="root:Milvus"
)

schema = client.create_schema()

# Add the partition key
schema.add_field(
    field_name="my_varchar", 
    datatype=DataType.VARCHAR, 
    max_length=512,
    # highlight-next-line
    is_partition_key=True,
)

import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;

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

// Create schema
CreateCollectionReq.CollectionSchema schema = client.createSchema();

// Add the partition key
schema.addField(AddFieldReq.builder()
        .fieldName("my_varchar")
        .dataType(DataType.VarChar)
        .maxLength(512)
        // highlight-next-line
        .isPartitionKey(true)
        .build());

import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";

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

// 3. Create a collection in customized setup mode
// 3.1 Define fields
const fields = [
    {
        name: "my_varchar",
        data_type: DataType.VarChar,
        max_length: 512,
        // highlight-next-line
        is_partition_key: true
    }
]

export schema='{
        "autoId": true,
        "enabledDynamicField": false,
        "fields": [
            {
                "fieldName": "my_id",
                "dataType": "Int64",
                "isPrimary": true
            },
            {
                "fieldName": "my_vector",
                "dataType": "FloatVector",
                "elementTypeParams": {
                    "dim": "5"
                }
            },
            {
                "fieldName": "my_varchar",
                "dataType": "VarChar",
                "isPartitionKey": true,
                "elementTypeParams": {
                    "max_length": 512
                }
            }
        ]
    }'

設定分割區號碼

當你指定一個集合中的標量欄位作為分區鍵時,Milvus 會自動在集合中建立 16 個分區。當接收到一個實體時,Milvus 會根據該實體的 Partition Key 值選擇一個分區,並將該實體儲存於該分區中,導致某些或所有分區持有不同 Partition Key 值的實體。

您也可以決定要與集合一起建立的分割區數量。只有當您指定一個標量欄位作為 Partition Key 時,這才有效。

client.create_collection(
    collection_name="my_collection",
    schema=schema,
    # highlight-next-line
    num_partitions=1024
)

import io.milvus.v2.service.collection.request.CreateCollectionReq;

CreateCollectionReq createCollectionReq = CreateCollectionReq.builder()
                .collectionName("my_collection")
                .collectionSchema(schema)
                .numPartitions(1024)
                .build();
        client.createCollection(createCollectionReq);

await client.create_collection({
    collection_name: "my_collection",
    schema: schema,
    num_partitions: 1024
})

export params='{
    "partitionsNum": 1024
}'

export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d "{
    \"collectionName\": \"myCollection\",
    \"schema\": $schema,
    \"params\": $params
}"

建立篩選條件

在啟用了分割區金鑰功能的資料集中執行 ANN 搜尋時,您需要在搜尋請求中包含涉及分割區金鑰的篩選表達式。在篩選表達式中,您可以限制 Partition Key 的值在特定範圍內,這樣 Milvus 就可以將搜尋範圍限制在相對應的分區內。

在處理刪除作業時,建議包含指定單一分割區金鑰的篩選表達式,以達到更有效率的刪除。這種方法可將刪除作業限制在特定的分割區內,減少壓縮期間的寫入放大,並節省壓縮和索引的資源。

以下範例展示基於 Partition-Key 的篩選方式,其基礎為特定的 Partition Key 值和一組 Partition Key 值。

# Filter based on a single partition key value, or
filter='partition_key == "x" && <other conditions>'

# Filter based on multiple partition key values
filter='partition_key in ["x", "y", "z"] && <other conditions>'

// Filter based on a single partition key value, or
String filter = "partition_key == 'x' && <other conditions>";

// Filter based on multiple partition key values
String filter = "partition_key in ['x', 'y', 'z'] && <other conditions>";

// Filter based on a single partition key value, or
const filter = 'partition_key == "x" && <other conditions>'

// Filter based on multiple partition key values
const filter = 'partition_key in ["x", "y", "z"] && <other conditions>'

# Filter based on a single partition key value, or
export filter='partition_key == "x" && <other conditions>'

# Filter based on multiple partition key values
export filter='partition_key in ["x", "y", "z"] && <other conditions>'

您必須以指定為分割區金鑰的欄位名稱取代partition_key

使用分割區金鑰隔離

在多租戶情境中,您可以指定與租戶身分相關的標量欄位為分割區金鑰,並根據此標量欄位中的特定值建立篩選器。為了進一步改善類似情況下的搜尋效能,Milvus 介紹了分割區金鑰隔離功能。

Partition Key Isolation 分割區金鑰隔離

如上圖所示,Milvus 根據分區鍵值將實體分組,並為每個分組建立獨立索引。收到搜尋請求後,Milvus 會根據篩選條件中指定的 Partition Key 值定位索引,並將搜尋範圍限制在索引所包含的實體內,從而避免在搜尋過程中掃描不相關的實體,大幅提升搜尋效能。 啟用 Partition Key Isolation 功能後,您可以在基於 Partition Key 的篩選條件中只包含特定值,以便 Milvus 能將搜尋範圍限制在符合條件的索引所包含的實體內。

目前,「分割區金鑰隔離」功能僅適用於索引類型設定為 HNSW 的搜尋。

啟用分割區金鑰隔離

以下程式碼範例說明如何啟用分割區金鑰隔離。

client.create_collection(
    collection_name="my_collection",
    schema=schema,
    # highlight-next-line
    properties={"partitionkey.isolation": True}
)

import io.milvus.v2.service.collection.request.CreateCollectionReq;

Map<String, String> properties = new HashMap<>();
properties.put("partitionkey.isolation", "true");

CreateCollectionReq createCollectionReq = CreateCollectionReq.builder()
        .collectionName("my_collection")
        .collectionSchema(schema)
        .numPartitions(1024)
        .properties(properties)
        .build();
client.createCollection(createCollectionReq);

res = await client.alterCollection({
    collection_name: "my_collection",
    properties: {
        "partitionkey.isolation": true
    }
})

export params='{
    "partitionKeyIsolation": true
}'

export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d "{
    \"collectionName\": \"myCollection\",
    \"schema\": $schema,
    \"params\": $params
}"

啟用磁碟分割區金鑰隔離後,您仍可以依照Set Partition Numbers(設定磁碟分割區號碼)一節所述,設定磁碟分割區金鑰和磁碟分割區號碼。請注意,基於分割區金鑰的篩選程式應該只包含特定的分割區金鑰值。

免費嘗試托管的 Milvus

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

開始使用
反饋

這個頁面有幫助嗎?