🚀 免费试用 Zilliz Cloud,完全托管的 Milvus,体验 10 倍的性能提升!立即试用>

Milvus
Zilliz
首页
  • 用户指南
  • Home
  • Docs
  • 用户指南

  • 搜索和 Rerankers

  • 使用 Partition Key

使用分区密钥

分区关键字是一种基于分区的搜索优化解决方案。通过指定特定标量字段作为 Partition Key,并在搜索过程中根据 Partition Key 指定过滤条件,可以将搜索范围缩小到多个分区,从而提高搜索效率。本文将介绍如何使用 Partition Key 以及相关注意事项。

概述

在 Milvus 中,你可以使用分区来实现数据隔离,并通过将搜索范围限制在特定分区来提高搜索性能。如果选择手动管理分区,可以在 Collections 中创建最多 1,024 个分区,并根据特定规则将实体插入这些分区,这样就可以通过限制在特定数量的分区内进行搜索来缩小搜索范围。

Milvus 引入了分区密钥,供你在数据隔离中重复使用分区,以克服在集合中创建分区数量的限制。创建 Collections 时,可以使用标量字段作为 Partition Key。一旦集合准备就绪,Milvus 就会在集合内创建指定数量的分区,每个分区都与分区密钥中的值范围相对应。收到插入的实体后,Milvus 会根据它们的 Partition Key 值把它们存储到不同的分区中。

Partition v.s. Partition Key 分区对分区密钥

下图说明了 Milvus 如何在启用或未启用分区键功能的情况下处理 Collections 中的搜索请求。

  • 如果禁用了 Partition Key,Milvus 会在 Collections 中搜索与查询向量最相似的实体。如果知道哪个分区包含最相关的结果,就可以缩小搜索范围。

  • 如果启用了分区关键字,Milvus 会根据搜索过滤器中指定的分区关键字值确定搜索范围,并只扫描分区内匹配的实体。

With or Without Partition Key 有无分区密钥

使用分区密钥

要使用分区密钥,您需要

  • 设置分区密钥。

  • 设置要创建的分区数量(可选),以及

  • 根据分区密钥创建过滤条件。

设置分区密钥

要将标量字段指定为 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
                }
            }
        ]
    }'

设置分区编号

当你指定一个 Collections 中的标量字段作为 Partition Key 时,Milvus 会自动在 Collections 中创建 16 个分区。当接收到一个实体时,Milvus 会根据这个实体的 Partition Key 值选择一个分区,并将实体存储在分区中,从而导致部分或所有分区持有不同 Partition Key 值的实体。

您还可以确定与 Collections 一起创建的分区数量。这只有在将标量字段指定为 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
}"

创建过滤条件

在启用分区关键字功能的 Collections 中进行 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 替换为指定为分区密钥的字段名称。

使用 Partition Key 隔离

在多租户场景中,可以将与租户身份相关的标量字段指定为分区密钥,并根据此标量字段中的特定值创建过滤器。为了进一步提高类似情况下的搜索性能,Milvus 引入了分区密钥隔离功能。

Partition Key Isolation 分区密钥隔离

如上图所示,Milvus 根据分区键值对实体进行分组,并为每个分组创建单独的索引。收到搜索请求后,Milvus 会根据过滤条件中指定的 Partition Key 值定位索引,并将搜索范围限制在索引所包含的实体内,从而避免在搜索过程中扫描不相关的实体,大大提高搜索性能。 启用 Partition Key Isolation 后,可以在基于 Partition Key 的过滤条件中只包含特定值,这样 Milvus 就能将搜索范围限制在索引所包含的匹配实体内。

目前,分区密钥隔离功能只适用于索引类型设置为 HNSW 的搜索。

启用分区密钥隔离功能

以下代码示例演示了如何启用 Partition Key Isolation。

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
}"

启用分区密钥隔离(Partition Key Isolation)后,仍可按照设置分区编号(Set Partition Numbers)中的说明设置分区密钥和分区编号。请注意,基于 Partition Key 的过滤器应只包含特定的 Partition Key 值。

想要更快、更简单、更好用的 Milvus SaaS服务 ?

Zilliz Cloud是基于Milvus的全托管向量数据库,拥有更高性能,更易扩展,以及卓越性价比

免费试用 Zilliz Cloud
反馈

此页对您是否有帮助?