استخدام مفتاح التقسيم
مفتاح التقسيم هو حل لتحسين البحث استناداً إلى الأقسام. من خلال تعيين حقل قياسي محدد كمفتاح التقسيم وتحديد شروط التصفية بناءً على مفتاح التقسيم أثناء البحث، يمكن تضييق نطاق البحث إلى عدة أقسام، وبالتالي تحسين كفاءة البحث. ستقدم هذه المقالة كيفية استخدام مفتاح التقسيم والاعتبارات ذات الصلة.
نظرة عامة
في Milvus، يمكنك استخدام الأقسام لتنفيذ فصل البيانات وتحسين أداء البحث من خلال تقييد نطاق البحث إلى أقسام محددة. إذا اخترت إدارة الأقسام يدويًا، يمكنك إنشاء 1024 قسمًا كحد أقصى في مجموعة ما، وإدراج كيانات في هذه الأقسام استنادًا إلى قاعدة محددة بحيث يمكنك تضييق نطاق البحث عن طريق تقييد عمليات البحث ضمن عدد محدد من الأقسام.
يقدم لك Milvus مفتاح التقسيم لتتمكن من إعادة استخدام الأقسام في فصل البيانات للتغلب على الحد الأقصى لعدد الأقسام التي يمكنك إنشاؤها في مجموعة. عند إنشاء مجموعة، يمكنك استخدام حقل قياسي كمفتاح التقسيم. بمجرد أن تصبح المجموعة جاهزة، يقوم Milvus بإنشاء العدد المحدد من الأقسام داخل المجموعة. عند استلام كيان مُدرَج، يقوم Milvus بحساب قيمة تجزئة باستخدام قيمة مفتاح التقسيم للكيان، وينفذ عملية تعديل بناءً على قيمة التجزئة والخاصية partitions_num للمجموعة للحصول على معرّف القسم الهدف، ويخزن الكيان في القسم الهدف.
التقسيم مقابل مفتاح التقسيم
يوضح الشكل التالي كيفية معالجة Milvus لطلبات البحث في مجموعة مع تمكين ميزة مفتاح التقسيم أو بدونها.
إذا تم تعطيل مفتاح التقسيم، يبحث Milvus عن الكيانات الأكثر تشابهًا مع متجه الاستعلام داخل المجموعة. يمكنك تضييق نطاق البحث إذا كنت تعرف القسم الذي يحتوي على أكثر النتائج ذات الصلة.
إذا تم تمكين مفتاح التقسيم، يحدد Milvus نطاق البحث استنادًا إلى قيمة مفتاح التقسيم المحددة في عامل تصفية البحث ويفحص فقط الكيانات الموجودة داخل الأقسام التي تتطابق.
مع وبدون مفتاح التقسيم
استخدام مفتاح التقسيم
لاستخدام مفتاح التقسيم، تحتاج إلى
تعيين عدد الأقسام المراد إنشاؤها (اختياري)، و
تعيين مفتاح التقسيم
لتعيين حقل قياسي كمفتاح التقسيم، تحتاج إلى تعيين السمة is_partition_key الخاصة به إلى true عند إضافة الحقل القياسي.
عندما تقوم بتعيين حقل قياسي كمفتاح التقسيم، لا يمكن أن تكون قيم الحقل فارغة أو فارغة.
from pymilvus import (
MilvusClient, DataType
)
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus"
)
schema = client.create_schema()
schema.add_field(field_name="id",
datatype=DataType.INT64,
is_primary=True)
schema.add_field(field_name="vector",
datatype=DataType.FLOAT_VECTOR,
dim=5)
# Add the partition key
schema.add_field(
field_name="my_varchar",
datatype=DataType.VARCHAR,
max_length=512,
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();
schema.addField(AddFieldReq.builder()
.fieldName("id")
.dataType(DataType.Int64)
.isPrimaryKey(true)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("vector")
.dataType(DataType.FloatVector)
.dimension(5)
.build());
// Add the partition key
schema.addField(AddFieldReq.builder()
.fieldName("my_varchar")
.dataType(DataType.VarChar)
.maxLength(512)
.isPartitionKey(true)
.build());
import (
"context"
"fmt"
"github.com/milvus-io/milvus/client/v2/column"
"github.com/milvus-io/milvus/client/v2/entity"
"github.com/milvus-io/milvus/client/v2/index"
"github.com/milvus-io/milvus/client/v2/milvusclient"
)
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
milvusAddr := "localhost:19530"
client, err := milvusclient.New(ctx, &milvusclient.ClientConfig{
Address: milvusAddr,
})
if err != nil {
fmt.Println(err.Error())
// handle error
}
defer client.Close(ctx)
schema := entity.NewSchema().WithDynamicFieldEnabled(false)
schema.WithField(entity.NewField().
WithName("id").
WithDataType(entity.FieldTypeInt64).
WithIsPrimaryKey(true),
).WithField(entity.NewField().
WithName("my_varchar").
WithDataType(entity.FieldTypeVarChar).
WithIsPartitionKey(true).
WithMaxLength(512),
).WithField(entity.NewField().
WithName("vector").
WithDataType(entity.FieldTypeFloatVector).
WithDim(5),
)
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,
is_partition_key: true
}
]
export schema='{
"autoId": true,
"enabledDynamicField": false,
"fields": [
{
"fieldName": "id",
"dataType": "Int64",
"isPrimary": true
},
{
"fieldName": "vector",
"dataType": "FloatVector",
"elementTypeParams": {
"dim": "5"
}
},
{
"fieldName": "my_varchar",
"dataType": "VarChar",
"isPartitionKey": true,
"elementTypeParams": {
"max_length": 512
}
}
]
}'
تعيين أرقام التقسيم
عندما تقوم بتعيين حقل قياسي في مجموعة كمفتاح قسم، يقوم Milvus تلقائيًا بإنشاء 16 قسمًا في المجموعة. عند استلام أحد الكيانات، يختار Milvus قسمًا استنادًا إلى قيمة مفتاح التقسيم لهذا الكيان ويخزن الكيان في القسم، مما يؤدي إلى احتواء بعض أو كل الأقسام على كيانات بقيم مفاتيح أقسام مختلفة.
يمكنك أيضًا تحديد عدد الأقسام المراد إنشاؤها مع المجموعة. لا يكون هذا صالحًا إلا إذا كان لديك حقل قياسي معيّن كمفتاح التقسيم.
client.create_collection(
collection_name="my_collection",
schema=schema,
num_partitions=128
)
import io.milvus.v2.service.collection.request.CreateCollectionReq;
CreateCollectionReq createCollectionReq = CreateCollectionReq.builder()
.collectionName("my_collection")
.collectionSchema(schema)
.numPartitions(128)
.build();
client.createCollection(createCollectionReq);
err = client.CreateCollection(ctx,
milvusclient.NewCreateCollectionOption("my_collection", schema).
WithNumPartitions(128))
if err != nil {
fmt.Println(err.Error())
// handle error
}
await client.create_collection({
collection_name: "my_collection",
schema: schema,
num_partitions: 128
})
export params='{
"partitionsNum": 128
}'
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\": \"my_collection\",
\"schema\": $schema,
\"params\": $params
}"
إنشاء شرط التصفية
عند إجراء عمليات بحث ANN في مجموعة مع تمكين ميزة مفتاح التقسيم، تحتاج إلى تضمين تعبير تصفية يتضمن مفتاح التقسيم في طلب البحث. في تعبير التصفية، يمكنك في تعبير التصفية تقييد قيمة مفتاح التقسيم ضمن نطاق محدد بحيث يقيد Milvus نطاق البحث ضمن الأقسام المقابلة.
عند تنفيذ عمليات الحذف، من المستحسن تضمين تعبير تصفية يحدد مفتاح قسم واحد لتحقيق حذف أكثر كفاءة. يحد هذا النهج عملية الحذف من عملية الحذف إلى قسم معين، مما يقلل من تضخيم الكتابة أثناء الضغط ويحافظ على الموارد اللازمة للضغط والفهرسة.
توضّح الأمثلة التالية التصفية المستندة إلى مفتاح التقسيم استنادًا إلى قيمة مفتاح قسم محدد ومجموعة من قيم مفاتيح التقسيم.
# 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
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
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 ميزة عزل مفتاح التقسيم.
عزل مفتاح التقسيم
كما هو موضح في الشكل أعلاه، يقوم Milvus بتجميع الكيانات بناءً على قيمة مفتاح التقسيم وإنشاء فهرس منفصل لكل مجموعة من هذه المجموعات. عند تلقي طلب بحث، يقوم ميلفوس بتحديد موقع الفهرس بناءً على قيمة مفتاح التقسيم المحددة في شرط التصفية ويقيد نطاق البحث داخل الكيانات المضمنة في الفهرس، وبالتالي تجنب مسح الكيانات غير ذات الصلة أثناء البحث وتحسين أداء البحث بشكل كبير.
بمجرد تمكين عزل مفتاح التقسيم، يجب عليك تضمين قيمة محددة واحدة فقط في عامل التصفية المستند إلى مفتاح التقسيم حتى يتمكن ميلفوس من تقييد نطاق البحث داخل الكيانات المضمنة في الفهرس التي تتطابق.
في الوقت الحالي، تنطبق ميزة عزل مفتاح التقسيم فقط على عمليات البحث مع تعيين نوع الفهرس إلى HNSW.
تمكين عزل مفتاح التقسيم
توضح الأمثلة البرمجية التالية كيفية تمكين عزل مفتاح التقسيم.
client.create_collection(
collection_name="my_collection",
schema=schema,
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)
.properties(properties)
.build();
client.createCollection(createCollectionReq);
err = client.CreateCollection(ctx,
milvusclient.NewCreateCollectionOption("my_collection", schema).
WithProperty("partitionkey.isolation", true))
if err != nil {
fmt.Println(err.Error())
// handle error
}
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\": \"my_collection\",
\"schema\": $schema,
\"params\": $params
}"
بمجرد تمكين عزل مفتاح القسم، لا يزال بإمكانك تعيين مفتاح القسم وعدد الأقسام كما هو موضح في تعيين أرقام الأقسام. لاحظ أنه يجب أن يتضمن عامل التصفية المستند إلى مفتاح التقسيم قيمة مفتاح قسم محدد فقط.