استخدام حقول المصفوفات

يشرح هذا الدليل كيفية استخدام حقول المصفوفات، مثل إدراج قيم المصفوفات، وإنشاء فهارس على حقول المصفوفات والمتجهات، بالإضافة إلى البحث والاستعلام في حقول المصفوفات باستخدام عوامل التشغيل الأساسية والمتقدمة.

المتطلبات الأساسية

تأكد من أن لديك ما يلي:

  • ميلفوس مثبتاً ومشغلاً. للحصول على معلومات حول كيفية تثبيت Milvus، راجع تثبيت Milvus.
  • تثبيت أحد حزم Milvus SDKs في بيئتك. للحصول على التفاصيل، راجع تثبيت حزم SDKs.

إعداد البيانات مع حقل مصفوفة

يدعم Milvus المصفوفات كأحد أنواع بيانات الحقل. يجب أن تحتوي المصفوفة في مجموعة Milvus دائمًا على عناصر من نفس نوع البيانات، ويمكن أن يكون نوع البيانات لعناصر المصفوفة أيًا من أنواع البيانات المدعومة في Milvus. للحصول على قائمة بأنواع البيانات المدعومة، راجع أنواع البيانات المدعومة.

يقوم مقتطف التعليمات البرمجية التالية بإنشاء مجموعة بيانات عشوائية تحتوي على حقل مصفوفة باسم color_coord ، مع جميع عناصر نوع بيانات interger.

import random

colors = ["green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey"]
data = []

for i in range(1000):
    current_color = random.choice(colors)
    current_tag = random.randint(1000, 9999)
    current_coord = [ random.randint(0, 40) for _ in range(random.randint(3, 5)) ]
    data.append({
        "id": i,
        "vector": [ random.uniform(-1, 1) for _ in range(5) ],
        "color": current_color,
        "color_tag": current_tag,
        "color_coord": current_coord,
    })

print(data[0])
import com.google.gson.Gson;
import com.google.gson.JsonObject;

import java.util.*;

List<String> colors = Arrays.asList("green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey");
List<JsonObject> data = new ArrayList<>();

Gson gson = new Gson();
Random rand = new Random();
for (int i=0; i<1000; i++) {
    String current_color = colors.get(rand.nextInt(colors.size()-1));
    Integer current_tag = rand.nextInt(8999) + 1000;

    // Generate an random-sized array
    int capacity = rand.nextInt(5) + 1;
    List<Integer> current_coord = new ArrayList<>();
    for (int j=0; j<capacity; j++) {
        current_coord.add(rand.nextInt(40));
    }

    JsonObject row = new JsonObject();
    row.addProperty("id", (long) i);
    row.add("vector", gson.toJsonTree(Arrays.asList(rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), rand.nextFloat(), rand.nextFloat())));
    row.addProperty("color", current_color);
    row.addProperty("color_tag", current_tag);
    row.add("color_coord", gson.toJsonTree(current_coord));
    data.add(row);
}

System.out.println(data.get(0));
const colors = ["green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey"];
let data = [];

for (let i = 0; i < 1000; i++) {
    const current_color = colors[Math.floor(Math.random() * colors.length)];
    const current_tag = Math.floor(Math.random() * 8999 + 1000);
    const current_coord = Array(Math.floor(Math.random() * 5 + 1)).fill(0).map(() => Math.floor(Math.random() * 40));

    data.push({
        id: i,
        vector: Array(5).fill(0).map(() => Math.random()),
        color: current_color,
        color_tag: current_tag,
        color_coord: current_coord,
    });
}

console.log(data[0]);

يقوم هذا المقتطف البرمجي بإعداد قائمة من الألوان العشوائية وإنشاء مجموعة بيانات تحتوي على 1000 كيان. يحتوي كل كيان على معرّف، ومتجه من خمسة أرقام ذات فاصلة عائمة، ولون، وعلامة لون، وحقل صفيف color_coord يحتوي على ما بين 3 إلى 5 قيم صحيحة. تتم طباعة بيانات العينة للتحقق من بنيتها.

هيكل الإخراج:

{
    id: 0,
    vector: [
        0.0338537420906162,
        0.6844108238358322,
        0.28410588909961754,
        0.09752595400212116,
        0.22671013058761114
    ],
    color: 'orange',
    color_tag: 5677,
    color_coord: [ 3, 0, 18, 29 ]
}

إعداد MilvusClient

للتفاعل مع Milvus، قم بإعداد عميل Milvus من خلال تحديد عنوان الخادم.

from pymilvus import MilvusClient, DataType

SERVER_ADDR = "http://localhost:19530"

client = MilvusClient(uri=SERVER_ADDR)
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.common.DataType;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.*;
import io.milvus.v2.service.index.request.CreateIndexReq;
import io.milvus.v2.service.vector.request.*;
import io.milvus.v2.service.vector.response.*;

String SERVER_ADDR = "http://localhost:19530";

// 1. Connect to Milvus server
ConnectConfig connectConfig = ConnectConfig.builder()
    .uri(SERVER_ADDR)
    .build();

MilvusClientV2 client = new MilvusClientV2(connectConfig);
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";

// Connect to Milvus server
const address = "http://localhost:19530";

const milvusClient = new MilvusClient({address: address});

إنشاء مجموعة مع حقل مصفوفة

تعريف مخطط المجموعة

يحدد المخطط بنية المجموعة، بما في ذلك الحقول وأنواع بياناتها. يُعرّف المثال أدناه مخطط مجموعة يطابق نموذج البيانات التي تم إنشاؤها في القسم السابق.

لتكوين حقل مصفوفة في مجموعة:

  1. قم بتعيين datatype: قم بتكوينه على أنه DataType.ARRAY.
  2. حدد element_type: اختر نوع البيانات للعناصر في المصفوفة. يجب أن يكون لجميع العناصر في حقل الصفيف نفس نوع البيانات. في هذا المثال، يتم تعيين element_type على DataType.INT64.
  3. قم بتعيين max_capacity: قم بتعيين هذه المعلمة لتحديد الحد الأقصى لعدد العناصر التي يمكن أن يحتفظ بها حقل المصفوفة.
  1. قم بتعيين dataType: قم بتكوينه على أنه DataType.Array.
  2. حدد elementType: اختر نوع البيانات للعناصر في المصفوفة. يجب أن يكون لجميع العناصر في حقل الصفيف نفس نوع البيانات. في هذا المثال، يتم تعيين elementType على DataType.Int64.
  3. قم بتعيين maxCapacity: قم بتعيين هذه المعلمة لتحديد الحد الأقصى لعدد العناصر التي يمكن أن يحتفظ بها حقل المصفوفة.
  1. قم بتعيين data_type: قم بتكوينه على أنه DataType.Array.
  2. حدد element_type: اختر نوع البيانات للعناصر في المصفوفة. يجب أن يكون لجميع العناصر في حقل الصفيف نفس نوع البيانات. في هذا المثال، يتم تعيين element_type على DataType.Int64.
  3. تحديد max_capacity: قم بتعيين هذه المعلمة لتحديد الحد الأقصى لعدد العناصر التي يمكن أن يحتفظ بها حقل المصفوفة.

يعرّف المثال البرمجي أدناه مخطط المجموعة مع حقل مصفوفة color_coord ، بحد أقصى 5 عناصر وكل عنصر من نوع البيانات الصحيحة.

schema = client.create_schema(auto_id=False, enable_dynamic_field=False)

schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)
schema.add_field(field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=5)
schema.add_field(field_name="color", datatype=DataType.VARCHAR, max_length=512)
schema.add_field(field_name="color_tag", datatype=DataType.INT64)
schema.add_field(field_name="color_coord", datatype=DataType.ARRAY, element_type=DataType.INT64, max_capacity=5)
// Create schema
CreateCollectionReq.CollectionSchema schema = client.createSchema();

// Add fields to schema
schema.addField(AddFieldReq.builder()
        .fieldName("id")
        .dataType(DataType.Int64)
        .isPrimaryKey(true)
        .autoID(false)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("vector")
        .dataType(DataType.FloatVector)
        .dimension(5)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("color")
        .dataType(DataType.VarChar)
        .maxLength(512)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("color_tag")
        .dataType(DataType.Int64)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("color_coord")
        .dataType(DataType.Array)
        .elementType(DataType.Int64)
        .maxCapacity(5)
        .build());
const fields = [
    {
        name: "id",
        data_type: DataType.Int64,
        is_primary_key: true,
        auto_id: false
    },
    {
        name: "vector",
        data_type: DataType.FloatVector,
        dim: 5
    },
    {
        name: "color",
        data_type: DataType.VarChar,
        max_length: 512
    },
    {
        name: "color_tag",
        data_type: DataType.Int64,
    },
    {
        name: "color_coord",
        data_type: DataType.Array,
        element_type: DataType.Int64,
        max_capacity: 5
    }
];

لمزيد من المعلومات حول الأساليب والمعلمات راجع إنشاء_شيما وإضافة_حقل.

لمزيد من المعلومات حول الأساليب والمعلمات ارجع إلى createSchema و addField.

لمزيد من المعلومات حول الأساليب والمعلمات راجع createCollection (إنشاء مجموعة).

إنشاء المجموعة

بعد ذلك، قم بإنشاء المجموعة باستخدام المخطط المحدد.

client.create_collection(collection_name="test_collection", schema=schema)
client.list_collections()

# Output:
# ['test_collection']
CreateCollectionReq customizedSetupReq = CreateCollectionReq.builder()
    .collectionName("test_collection")
    .collectionSchema(schema)
    .build();

client.createCollection(customizedSetupReq);
await client.createCollection({
    collection_name: "test_collection",
    fields: fields
});

const res = await client.listCollections({collection_name: "test_collection"});

console.log("Existing collections: " + res.collection_names);

// Output:
// Existing collections: test_collection

للمزيد من المعلومات حول الأساليب والمعلمات ارجع إلى create_collection و list_collections.

لمزيد من المعلومات حول الأساليب والمعلمات ارجع إلى createCollection.

لمزيد من المعلومات حول الأساليب والمعلمات ارجع إلى createCollection و listCollections.

إنشاء فهارس

تعمل الفهارس على تحسين أداء عمليات البحث والاستعلام. في ميلفوس، يمكنك إنشاء فهارس على كل من الحقول المتجهة والحقول القياسية. في هذا المثال، سنقوم بإنشاء فهرس IVF_FLAT على الحقل المتجه vector وفهرس INVERTED على الحقل الصفيف color_coord. لمزيد من المعلومات حول الفهارس، راجع فهرس الحقول المتجهة وفهرس الحقول القياسية.

فهرس الحقل المتجه

يمكن أن يؤدي إنشاء فهرس على حقل متجه إلى تحسين أداء البحث عن تشابه المتجهات، وهو أمر ضروري لكل عملية بحث.

يقوم المثال أدناه بإنشاء فهرس من النوع IVF_FLAT على الحقل المتجه vector.

index_params = client.prepare_index_params()

index_params.add_index(
    field_name="vector",
    metric_type="COSINE",
    index_type="IVF_FLAT",
    index_name="vector_index",
    params={"nlist": 128}
)

client.create_index(collection_name="test_collection", index_params=index_params)
client.describe_index(collection_name="test_collection", index_name="vector_index")

# Output:
# {'nlist': '128',
#  'index_type': 'IVF_FLAT',
#  'metric_type': 'COSINE',
#  'field_name': 'vector',
#  'index_name': 'vector_index'}
IndexParam indexParam = IndexParam.builder()
        .metricType(IndexParam.MetricType.COSINE)
        .indexType(IndexParam.IndexType.IVF_FLAT)
        .fieldName("vector")
        .indexName("vector_index")
        .build();
CreateIndexReq createIndexReq = CreateIndexReq.builder()
        .collectionName("test_collection")
        .indexParams(Collections.singletonList(indexParam))
        .build();
client.createIndex(createIndexReq);
await client.createIndex({
    collection_name: "test_collection",
    field_name: "vector",
    index_type: "IVF_FLAT",
    metric_type: "COSINE",   
    index_name: "vector_index",
    params: { "nlist": 128 }
});

res = await client.describeIndex({
    collection_name: "test_collection",
    index_name: "vector_index"
});

console.log("Vector index description: " + JSON.stringify(res));

// Output:
// Vector index description: {"index_descriptions":[{"params":[{"key":"params","value":"{\"nlist\":128}"},{"key":"index_type","value":"IVF_FLAT"},{"key":"metric_type","value":"COSINE"}],"index_name":"vector_index","indexID":"451543183233666062","field_name":"vector","indexed_rows":"0","total_rows":"0","state":"Finished","index_state_fail_reason":"","pending_index_rows":"0"}],"status":{"extra_info":{},"error_code":"Success","reason":"","code":0,"retriable":false,"detail":""}}

لمزيد من المعلومات حول الأساليب والمعلمات ارجع إلى Prep_index_params وCreat_index وSow_index.

لمزيد من المعلومات حول الطرق والمعلمات راجع فهرس_بارام و إنشاء_الفهرس.

لمزيد من المعلومات حول الأساليب والمعلمات ارجع إلى إنشاء_الفهرس ووصف_الفهرس.

حقل صفيف الفهرس

يمكن أن يؤدي إنشاء فهرس على حقل قياسي إلى تحسين أداء استرجاع الاستعلامات على ذلك الحقل، وهو أمر اختياري لكن يوصى به لمجموعات البيانات الكبيرة.

في هذا المثال، سننشئ فهرسًا مقلوبًا على حقل الصفيف color_coord. سيسمح لنا ذلك بتسريع عملية التصفية بناءً على هذا الحقل. يُظهر الفهرس المقلوب أداءً إجماليًا ممتازًا، حيث يتفوق بشكل كبير على التصفية باستخدام القوة الغاشمة باستخدام البيانات الأولية عندما لا يتم استرجاع البيانات بشكل متكرر، ويحافظ على أداء مماثل مع عمليات الاسترجاع المتكررة. لمزيد من المعلومات حول الفهارس المقلوبة، راجع الفهرس المقلوب، راجع فهرس Scalar Index.

index_params = client.prepare_index_params()

index_params.add_index(
    field_name="color_coord",
    index_type="INVERTED",
    index_name="inverted_index"
)

client.create_index(collection_name="test_collection", index_params=index_params)
client.describe_index(collection_name="test_collection", index_name="inverted_index")

# Output:
# {'index_type': 'INVERTED',
#  'field_name': 'color_coord',
#  'index_name': 'inverted_index'}
indexParam = IndexParam.builder()
        .indexType(IndexParam.IndexType.INVERTED)
        .fieldName("color_coord")
        .indexName("inverted_index")
        .build();
createIndexReq = CreateIndexReq.builder()
        .collectionName("test_collection")
        .indexParams(Collections.singletonList(indexParam))
        .build();
client.createIndex(createIndexReq);
await client.createIndex({
    collection_name: "test_collection",
    field_name: "color_coord",
    index_type: "INVERTED",
    index_name: "inverted_index"
});

res = await client.describeIndex({
    collection_name: "test_collection",
    index_name: "inverted_index"
});

console.log("Array index description: " + JSON.stringify(res));

// Output:
// Array index description: {"index_descriptions":[{"params":[{"key":"index_type","value":"INVERTED"}],"index_name":"inverted_index","indexID":"451543183233667243","field_name":"color_coord","indexed_rows":"0","total_rows":"0","state":"Finished","index_state_fail_reason":"","pending_index_rows":"0"}],"status":{"extra_info":{},"error_code":"Success","reason":"","code":0,"retriable":false,"detail":""}}

لمزيد من المعلومات حول الأساليب والمعلمات ارجع إلى Prep_index_params وCreat_index وSow_index.

لمزيد من المعلومات حول الطرق والمعلمات راجع فهرس_بارام و إنشاء_الفهرس.

لمزيد من المعلومات حول الأساليب والمعلمات ارجع إلى إنشاء_الفهرس ووصف_الفهرس.

إدراج البيانات

بمجرد إنشاء المجموعة والفهارس، يمكننا إدراج البيانات في المجموعة. تقوم هذه الخطوة بإدراج 1000 كيان في test_collection.

res = client.insert(collection_name="test_collection", data=data)
print(res)

# Output:
# {'insert_count': 1000, 'ids': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 810, 811, 812, 813, 814, 815, 816, 817, 818, 819, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, 864, 865, 866, 867, 868, 869, 870, 871, 872, 873, 874, 875, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 996, 997, 998, 999], 'cost': 0}
InsertReq insertReq = InsertReq.builder()
    .collectionName("test_collection")
    .data(data)
    .build();

InsertResp insertResp = client.insert(insertReq);
res = await client.insert({
    collection_name: "test_collection",
    data: data
});

console.log(`Inserted ${res.insert_cnt} entities`);

// Output:
// Inserted 1000 entities

تحميل المجموعة

بعد إدراج البيانات، نحتاج إلى تحميل المجموعة لجعلها متاحة لعمليات البحث والاستعلام.

client.load_collection('test_collection')
LoadCollectionReq loadCollectionReq = LoadCollectionReq.builder()
        .collectionName("test_collection")
        .build();
client.loadCollection(loadCollectionReq);
await client.loadCollection({
    collection_name: "test_collection"
});

res = await client.getLoadState({
    collection_name: "test_collection"
});

console.log("Collection load state: " + res.state);

// Output:
// Collection load state: LoadStateLoaded

التصفية العددية الأساسية

بمجرد إضافة جميع بياناتك، يمكنك إجراء عمليات بحث واستعلامات باستخدام العناصر الموجودة في حقل الصفيف بنفس الطريقة التي تستخدمها مع الحقل القياسي القياسي.

لمزيد من المعلومات حول المعلمات، راجع search() في مرجع SDK.

لمزيد من المعلومات حول المعلمات، راجع search() في مرجع SDK.

لمزيد من المعلومات عن المعلمات، ارجع إلى search() في مرجع SDK.

# 4. Basic search with the array field
query_vectors = [ [ random.uniform(-1, 1) for _ in range(5) ]]

res = client.search(
    collection_name="test_collection",
    data=query_vectors,
    filter="color_coord[0] < 10",
    search_params={
        "metric_type": "COSINE",
        "params": {"nprobe": 16}
    },
    output_fields=["id", "color", "color_tag", "color_coord"],
    limit=3
)

print(res)

# Output:
# data: ["[{'id': 918, 'distance': 0.974249541759491, 'entity': {'color_coord': [4, 34, 9, 18, 29], 'id': 918, 'color': 'purple', 'color_tag': 2940}}, {'id': 822, 'distance': 0.9177230000495911, 'entity': {'color_coord': [7, 36, 32], 'id': 822, 'color': 'red', 'color_tag': 8519}}, {'id': 981, 'distance': 0.9116519689559937, 'entity': {'color_coord': [7, 16, 40, 32, 32], 'id': 981, 'color': 'pink', 'color_tag': 2992}}]"] , extra_info: {'cost': 0}
// 4. Basic search with an Array field
QueryReq queryReq = QueryReq.builder()
        .collectionName("test_collection")
        .filter("color_coord[0] in [7, 8, 9]")
        .outputFields(Arrays.asList("id", "color", "color_tag", "color_coord"))
        .limit(3L)
        .build();

QueryResp queryResp = client.query(queryReq);

System.out.println(queryResp.getQueryResults());

// Output:
// [
//  QueryResp.QueryResult(entity={color=black, color_tag=6107, id=8, color_coord=[8, 19, 31, 10]}), 
//  QueryResp.QueryResult(entity={color=blue, color_tag=3252, id=11, color_coord=[7, 16, 1]}),
//  QueryResp.QueryResult(entity={color=blue, color_tag=3069, id=16, color_coord=[9, 16, 19]})
// ]
const query_vectors = [Array(5).fill(0).map(() => Math.random())];

res = await client.search({
    collection_name: "test_collection",
    data: query_vectors,
    filter: "color_coord[0] < 10",
    output_fields: ["id", "color", "color_tag", "color_coord"],
    limit: 3,
    metric_type: "COSINE"
});

console.log("Search result: " + JSON.stringify(res));

// Output:
// Search result: [
//     {
//         "score": 0.9969238042831421,
//         "id": "212",
//         "color": "green",
//         "color_tag": "5603",
//         "color_coord": [
//             "9",
//             "14",
//             "22",
//             "4",
//             "35"
//         ]
//     },
//     {
//         "score": 0.9952742457389832,
//         "id": "339",
//         "color": "yellow",
//         "color_tag": "8867",
//         "color_coord": [
//             "8",
//             "0",
//             "6",
//             "19",
//             "23"
//         ]
//     },
//     {
//         "score": 0.9944050312042236,
//         "id": "24",
//         "color": "red",
//         "color_tag": "7686",
//         "color_coord": [
//             "6",
//             "17",
//             "6",
//             "32"
//         ]
//     }
// ]

التصفية المتقدمة

على غرار ما لدينا في حقل JSON، يوفر ميلفوس أيضًا عوامل تصفية متقدمة للمصفوفات، وهي ARRAY_CONTAINS ، ARRAY_CONTAINS_ALL ، ، ARRAY_CONTAINS_ANY ، و ARRAY_LENGTH. لمزيد من المعلومات عن المشغلات، راجع مرجع عن مرشحات المصفوفات.

  • تصفية جميع الكيانات التي تحتوي على 10 في قيمها color_coord.

    # 5. Advanced query within the array field
    
    res = client.query(
        collection_name="test_collection",
        filter="ARRAY_CONTAINS(color_coord, 10)",
        output_fields=["id", "color", "color_tag", "color_coord"],
        limit=3
    )
    
    print(res)
    
    # Output:
    # data: ["{'id': 2, 'color': 'green', 'color_tag': 3676, 'color_coord': [26, 37, 30, 10]}", "{'id': 28, 'color': 'red', 'color_tag': 4735, 'color_coord': [30, 10, 40, 34]}", "{'id': 32, 'color': 'green', 'color_tag': 8816, 'color_coord': [10, 9, 24, 39]}"] , extra_info: {'cost': 0}
    
    // 5. Advanced query within an Array field
    queryReq = QueryReq.builder()
            .collectionName("test_collection")
            .filter("ARRAY_CONTAINS(color_coord, 10)")
            .outputFields(Arrays.asList("id", "color", "color_tag", "color_coord"))
            .limit(3)
            .build();
    
    queryResp = client.query(queryReq);
    
    System.out.println(queryResp.getQueryResults());
    
    // Output:
    // [
    //    QueryResp.QueryResult(entity={color=black, color_tag=6107, id=8, color_coord=[8, 19, 31, 10]}), 
    //    QueryResp.QueryResult(entity={color=brown, color_tag=7727, id=17, color_coord=[1, 10, 16, 29]}), 
    //    QueryResp.QueryResult(entity={color=orange, color_tag=8128, id=26, color_coord=[10, 16, 3, 3]})
    // ]
    
    // 5. Advanced search within the array field
    res = await client.search({
        collection_name: "test_collection",
        data: query_vectors,
        filter: "ARRAY_CONTAINS(color_coord, 10)",
        output_fields: ["id", "color", "color_tag", "color_coord"],
        limit: 3
    })
    
    console.log(JSON.stringify(res.results, null, 4))
    
    // Output
    // 
    // [
    //     {
    //         "score": 1.7962548732757568,
    //         "id": "696",
    //         "color": "red",
    //         "color_tag": "1798",
    //         "color_coord": [
    //             "33",
    //             "10",
    //             "37"
    //         ]
    //     },
    //     {
    //         "score": 1.7126177549362183,
    //         "id": "770",
    //         "color": "red",
    //         "color_tag": "1962",
    //         "color_coord": [
    //             "21",
    //             "23",
    //             "10"
    //         ]
    //     },
    //     {
    //         "score": 1.6707111597061157,
    //         "id": "981",
    //         "color": "yellow",
    //         "color_tag": "3100",
    //         "color_coord": [
    //             "28",
    //             "39",
    //             "10",
    //             "6"
    //         ]
    //     }
    // ]
    // 
    
  • تصفية جميع الكيانات التي تحتوي على 7 و 8 في قيم color_coord الخاصة بها.

    res = client.query(
        collection_name="test_collection",
        filter="ARRAY_CONTAINS_ALL(color_coord, [7, 8])",
        output_fields=["id", "color", "color_tag", "color_coord"],
        limit=3
    )
    
    print(res)
    
    # Output:
    # data: ["{'id': 147, 'color': 'brown', 'color_tag': 1287, 'color_coord': [7, 8, 11, 0]}", "{'id': 257, 'color': 'white', 'color_tag': 3641, 'color_coord': [2, 8, 31, 7]}", "{'id': 280, 'color': 'orange', 'color_tag': 1072, 'color_coord': [22, 7, 8]}"] , extra_info: {'cost': 0}
    
    queryReq = QueryReq.builder()
            .collectionName("test_collection")
            .filter("ARRAY_CONTAINS_ALL(color_coord, [7, 8])")
            .outputFields(Arrays.asList("id", "color", "color_tag", "color_coord"))
            .limit(3)
            .build();
    
    queryResp = client.query(queryReq);
    
    System.out.println(queryResp.getQueryResults());
    
    // Output:
    // [
    //  QueryResp.QueryResult(entity={color=blue, color_tag=6939, id=246, color_coord=[1, 8, 27, 7]}), 
    //  QueryResp.QueryResult(entity={color=brown, color_tag=6341, id=673, color_coord=[8, 7, 33, 20, 11]})
    // ]
    
    res = await client.search({
        collection_name: "test_collection",
        data: query_vectors,
        filter: "ARRAY_CONTAINS_ALL(color_coord, [7, 8])",
        output_fields: ["id", "color", "color_tag", "color_coord"],
        limit: 3
    })
    
    console.log(JSON.stringify(res.results, null, 4))
    
    // Output
    // 
    // [
    //     {
    //         "score": 0.8267516493797302,
    //         "id": "913",
    //         "color": "brown",
    //         "color_tag": "8897",
    //         "color_coord": [
    //             "39",
    //             "31",
    //             "8",
    //             "29",
    //             "7"
    //         ]
    //     },
    //     {
    //         "score": 0.6889009475708008,
    //         "id": "826",
    //         "color": "blue",
    //         "color_tag": "4903",
    //         "color_coord": [
    //             "7",
    //             "25",
    //             "5",
    //             "12",
    //             "8"
    //         ]
    //     },
    //     {
    //         "score": 0.5851659774780273,
    //         "id": "167",
    //         "color": "blue",
    //         "color_tag": "1550",
    //         "color_coord": [
    //             "8",
    //             "27",
    //             "7"
    //         ]
    //     }
    // ]
    // 
    
  • تصفية جميع الكيانات التي تحتوي على 7 أو 8 أو 9 في قيمها color_coord.

    res = client.query(
        collection_name="test_collection",
        filter="ARRAY_CONTAINS_ANY(color_coord, [7, 8, 9])",
        output_fields=["id", "color", "color_tag", "color_coord"],
        limit=3
    )
    
    print(res)
    
    # Output:
    # data: ["{'id': 0, 'color': 'white', 'color_tag': 2081, 'color_coord': [16, 7, 35, 5, 25]}", "{'id': 1, 'color': 'purple', 'color_tag': 4669, 'color_coord': [11, 9, 15, 38, 21]}", "{'id': 3, 'color': 'yellow', 'color_tag': 2612, 'color_coord': [0, 12, 22, 7]}"] , extra_info: {'cost': 0}
    
    queryReq = QueryReq.builder()
            .collectionName("test_collection")
            .filter("ARRAY_CONTAINS_ANY(color_coord, [7, 8, 9])")
            .outputFields(Arrays.asList("id", "color", "color_tag", "color_coord"))
            .limit(3)
            .build();
    
    queryResp = client.query(queryReq);
    
    System.out.println(queryResp.getQueryResults());
    
    // Output:
    // [
    //  QueryResp.QueryResult(entity={color=purple, color_tag=3687, id=1, color_coord=[22, 7, 29, 25]}), 
    //  QueryResp.QueryResult(entity={color=black, color_tag=6107, id=8, color_coord=[8, 19, 31, 10]}), 
    //  QueryResp.QueryResult(entity={color=blue, color_tag=3252, id=11, color_coord=[7, 16, 1]})
    // ]
    
    res = await client.search({
        collection_name: "test_collection",
        data: query_vectors,
        filter: "ARRAY_CONTAINS_ANY(color_coord, [7, 8, 9])",
        output_fields: ["id", "color", "color_tag", "color_coord"],
        limit: 3
    })
    
    console.log(JSON.stringify(res.results, null, 4))
    
    // Output
    // 
    // [
    //     {
    //         "score": 2.015894889831543,
    //         "id": "260",
    //         "color": "green",
    //         "color_tag": "5320",
    //         "color_coord": [
    //             "1",
    //             "7",
    //             "33",
    //             "13",
    //             "23"
    //         ]
    //     },
    //     {
    //         "score": 1.783075213432312,
    //         "id": "593",
    //         "color": "orange",
    //         "color_tag": "4079",
    //         "color_coord": [
    //             "8",
    //             "19"
    //         ]
    //     },
    //     {
    //         "score": 1.7713876962661743,
    //         "id": "874",
    //         "color": "blue",
    //         "color_tag": "7029",
    //         "color_coord": [
    //             "14",
    //             "8",
    //             "15"
    //         ]
    //     }
    // ]
    // 
    
  • تصفية الكيانات التي تحتوي على أربعة عناصر بالضبط.

    res = client.query(
        collection_name="test_collection",
        filter="ARRAY_LENGTH(color_coord) == 4",
        output_fields=["id", "color", "color_tag", "color_coord"],
        limit=3
    )
    
    print(res)
    
    # Output:
    # data: ["{'id': 2, 'color': 'green', 'color_tag': 3676, 'color_coord': [26, 37, 30, 10]}", "{'id': 3, 'color': 'yellow', 'color_tag': 2612, 'color_coord': [0, 12, 22, 7]}", "{'id': 4, 'color': 'green', 'color_tag': 6912, 'color_coord': [4, 5, 19, 28]}"] , extra_info: {'cost': 0}
    
    queryReq = QueryReq.builder()
            .collectionName("test_collection")
            .filter("ARRAY_LENGTH(color_coord) == 4")
            .outputFields(Arrays.asList("id", "color", "color_tag", "color_coord"))
            .limit(3)
            .build();
    
    queryResp = client.query(queryReq);
    
    System.out.println(queryResp.getQueryResults()); 
    
    // Output:
    // [
    //  QueryResp.QueryResult(entity={color=purple, color_tag=3687, id=1, color_coord=[22, 7, 29, 25]}),
    //  QueryResp.QueryResult(entity={color=yellow, color_tag=1990, id=3, color_coord=[26, 20, 15, 26]}),
    //  QueryResp.QueryResult(entity={color=purple, color_tag=3199, id=4, color_coord=[13, 19, 21, 30]})
    // ]
    
    res = await client.search({
    collection_name: "test_collection",
    data: query_vectors,
    filter: "ARRAY_LENGTH(color_coord) == 4",
    output_fields: ["id", "color", "color_tag", "color_coord"],
    limit: 3
    })
    
    console.log(JSON.stringify(res.results, null, 4))
    
    // Output
    // 
    // [
    //     {
    //         "score": 2.0404388904571533,
    //         "id": "439",
    //         "color": "orange",
    //         "color_tag": "7096",
    //         "color_coord": [
    //             "27",
    //             "34",
    //             "26",
    //             "39"
    //         ]
    //     },
    //     {
    //         "score": 1.9059759378433228,
    //         "id": "918",
    //         "color": "purple",
    //         "color_tag": "2903",
    //         "color_coord": [
    //             "28",
    //             "19",
    //             "36",
    //             "35"
    //         ]
    //     },
    //     {
    //         "score": 1.8385567665100098,
    //         "id": "92",
    //         "color": "yellow",
    //         "color_tag": "4693",
    //         "color_coord": [
    //             "1",
    //             "23",
    //             "2",
    //             "3"
    //         ]
    //     }
    // ]
    // 
    

الحدود

  • يجب أن تكون العناصر الموجودة في حقل ARRAY من نفس نوع البيانات، المحدد بواسطة element_type. يمكن استخدام أي نوع بيانات صالح متاح للحقول القياسية في ميلفوس element_type. للحصول على قائمة بأنواع البيانات المدعومة، راجع أنواع البيانات المدعومة.

  • يجب أن يكون عدد العناصر في حقل ARRAY أقل من أو يساوي السعة القصوى لحقل المصفوفة، المحددة بواسطة max_capacity.

مرجع عن مرشحات الصفيف

عند العمل مع حقول المصفوفات، يمكنك إحاطة قيمة السلسلة إما بعلامات اقتباس مزدوجة ("") أو علامات اقتباس مفردة (''). من المهم ملاحظة أن ميلفوس يخزن قيم السلسلة في حقل المصفوفة كما هي دون إجراء الهروب الدلالي أو التحويل. على سبيل المثال، سيتم حفظ "a'b" و "a'b" و"a'b" و" a'b" و "a ' b " كما هي، بينما سيتم التعامل مع "a'b" و "a'b" كقيم غير صالحة.

افترض أنه تم تعريف حقلي مصفوفة int_array و var_array. يصف الجدول التالي التعبيرات المنطقية المدعومة التي يمكنك استخدامها في expr عند البحث باستخدام حقول الصفيف.

المشغلأمثلةملاحظات
<‘int_array[0] < 3’يتم تقييم هذا التعبير إلى صواب إذا كانت قيمة int_array[0] أقل من 3.
>‘int_array[0] > 5’يتم تقييم هذا التعبير إلى صواب إذا كانت قيمة int_array[0] أكبر من 5.
==‘int_array[0] == 0’يتم تقييم هذا التعبير إلى صواب إذا كانت قيمة int_array[0] تساوي 0.
!=‘var_array[0] != "a"’يتم تقييم هذا التعبير إلى صواب إذا كانت قيمة var_array[0] لا تساوي “a”.
<=‘int_array[0] <= 3’يتم تقييم هذا التعبير إلى صواب إذا كانت قيمة int_array[0] أصغر من أو تساوي 3.
>=‘int_array[0] >= 10’يتم تقييم هذا التعبير إلى صواب إذا كانت قيمة int_array[0] أكبر من أو تساوي 10.
في'var_array[0] in ["str1", “str2”]'يتم تقييم هذا التعبير إلى صواب إذا كانت قيمة var_array[0] هي “str1” أو “str2”.
ليس في'int_array[0] not in [1, 2, 3]'يتم تقييم هذا التعبير إلى صواب إذا كانت قيمة int_array[0] ليست 1 أو 2 أو 3.
+, -, *, /, %, **‘int_array[0] + 100 > 200’يتم تقييم هذا التعبير إلى صواب إذا كانت قيمة int_array[0] + 100 أكبر من 200.
مثل (LIKE)‘var_array[0] like "prefix%"’يتم تقييم هذا التعبير على أنه صحيح إذا كانت قيمة var_array[0] مسبوقة ب “prefix”.
و (&&)‘var_array[0] like “prefix%” && int_array[0] <= 100’يتم تقييم هذا التعبير على أنه صواب إذا كانت قيمة var_array[0] مسبوقة بـ “prefix” ، وقيمة int_array[0] أصغر من أو تساوي 100.
أو (||)‘var_array[0] like “prefix%” || int_array[0] <= 100’يُقيّم هذا التعبير على أنه صواب إذا كانت قيمة var_array[0] مسبوقة ب “prefix” ، أو كانت قيمة int_array[0] أصغر من أو تساوي 100.
array_contains (ARRAY_CONTAINS)'array_contains(int_array, 100)'يتم تقييم هذا التعبير إلى صواب إذا كان int_array يحتوي على العنصر 100.
array_contains_all (ARRAY_CONTAINS_ALL)'array_contains_all(int_array, [1, 2, 3])'يتم تقييم هذا التعبير إلى صواب إذا كان int_array يحتوي على جميع العناصر 1 و 2 و 3.
array_contains_any (ARRAY_CONTAINS_ANY)'array_contains_any(var_array, ["a", "b", “c”])'يتم تقييم هذا التعبير على أنه صواب إذا كان var_array يحتوي على أي عنصر من “a” و “b” و “c”.
طول_المصفوفة‘array_length(int_array) == 10’يتم تقييم هذا التعبير إلى صواب إذا كان int_array يحتوي على 10 عناصر بالضبط.