🚀 جرب Zilliz Cloud، الـ Milvus المدارة بالكامل، مجاناً — تجربة أداء أسرع بـ 10 أضعاف! جرب الآن>>

milvus-logo
LFAI
الصفحة الرئيسية
  • دليل المستخدم
  • Home
  • Docs
  • دليل المستخدم

  • المخطط وحقول البيانات

  • حقل JSON

حقل JSON

JSON (تدوين كائنات JavaScript) هو تنسيق خفيف الوزن لتبادل البيانات يوفر طريقة مرنة لتخزين هياكل البيانات المعقدة والاستعلام عنها. في Milvus، يمكنك تخزين معلومات منظمة إضافية إلى جانب بيانات المتجهات باستخدام حقول JSON، مما يتيح عمليات بحث واستعلامات متقدمة تجمع بين تشابه المتجهات والتصفية المنظمة.

تعتبر حقول JSON مثالية للتطبيقات التي تتطلب بيانات وصفية لتحسين نتائج الاسترجاع. على سبيل المثال، في التجارة الإلكترونية، يمكن تعزيز ناقلات المنتجات بسمات مثل الفئة والسعر والعلامة التجارية. في أنظمة التوصيات، يمكن دمج ناقلات المستخدم مع التفضيلات والمعلومات الديموغرافية. فيما يلي مثال لحقل JSON نموذجي.

{
  "category": "electronics",
  "price": 99.99,
  "brand": "BrandA"
}

إضافة حقل JSON

لاستخدام حقول JSON في Milvus، قم بتعريف نوع الحقل ذي الصلة في مخطط المجموعة، مع تعيين datatype إلى نوع JSON المدعوم، أي JSON.

إليك كيفية تعريف مخطط مجموعة يتضمن حقل JSON.

from pymilvus import MilvusClient, DataType

client = MilvusClient(uri="http://localhost:19530")

schema = client.create_schema(
    auto_id=False,
    enable_dynamic_fields=True,
)

schema.add_field(field_name="metadata", datatype=DataType.JSON)
schema.add_field(field_name="pk", datatype=DataType.INT64, is_primary=True)
schema.add_field(field_name="embedding", datatype=DataType.FLOAT_VECTOR, dim=3)

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")
        .build());
        
CreateCollectionReq.CollectionSchema schema = client.createSchema();
schema.setEnableDynamicField(true);

schema.addField(AddFieldReq.builder()
        .fieldName("metadata")
        .dataType(DataType.JSON)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("pk")
        .dataType(DataType.Int64)
        .isPrimaryKey(true)
        .build());

schema.addField(AddFieldReq.builder()
        .fieldName("embedding")
        .dataType(DataType.FloatVector)
        .dimension(3)
        .build());

import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
const schema = [
  {
    name: "metadata",
    data_type: DataType.JSON,
  },
  {
    name: "pk",
    data_type: DataType.Int64,
    is_primary_key: true,
  },
  {
    name: "embedding",
    data_type: DataType.FloatVector,
    dim: 3,
  },
];

export jsonField='{
    "fieldName": "metadata",
    "dataType": "JSON"
}'

export pkField='{
    "fieldName": "pk",
    "dataType": "Int64",
    "isPrimary": true
}'

export vectorField='{
    "fieldName": "embedding",
    "dataType": "FloatVector",
    "elementTypeParams": {
        "dim": 3
    }
}'

export schema="{
    \"autoID\": false,
    \"fields\": [
        $jsonField,
        $pkField,
        $vectorField
    ]
}"

في هذا المثال، نضيف حقل JSON يسمى metadata لتخزين البيانات الوصفية الإضافية المتعلقة ببيانات المتجه، مثل فئة المنتج والسعر ومعلومات العلامة التجارية.

يكون الحقل الأساسي وحقل المتجه إلزاميًا عند إنشاء مجموعة. يعرّف الحقل الأساسي كل كيان بشكل فريد، في حين أن حقل المتجه مهم للبحث عن التشابه. لمزيد من التفاصيل، راجع الحقل الأساسي والمعرف التلقائي أو المتجه الكثيف أو المتجه الثنائي أو المتجه المتناثر.

إنشاء مجموعة

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


index_params = client.prepare_index_params()

index_params.add_index(
    field_name="embedding",
    index_type="AUTOINDEX",
    metric_type="COSINE"
)

import io.milvus.v2.common.IndexParam;
import java.util.*;

List<IndexParam> indexes = new ArrayList<>();
indexes.add(IndexParam.builder()
        .fieldName("embedding")
        .indexType(IndexParam.IndexType.AUTOINDEX)
        .metricType(IndexParam.MetricType.COSINE)
        .build());

const indexParams = {
    index_name: 'embedding_index',
    field_name: 'embedding',
    metricType: MetricType.CONSINE,
    index_type: IndexType.AUTOINDEX,
);

export indexParams='[
        {
            "fieldName": "embedding",
            "metricType": "COSINE",
            "indexType": "AUTOINDEX"
        }
    ]'

استخدم المخطط المحدد ومعلمات الفهرس لإنشاء مجموعة.

client.create_collection(
    collection_name="my_json_collection",
    schema=schema,
    index_params=index_params
)

CreateCollectionReq requestCreate = CreateCollectionReq.builder()
        .collectionName("my_json_collection")
        .collectionSchema(schema)
        .indexParams(indexes)
        .build();
client.createCollection(requestCreate);

client.create_collection({
    collection_name: "my_json_collection",
    schema: schema,
    index_params: indexParams
})

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

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

بعد إنشاء المجموعة، يمكنك إدراج البيانات التي تتضمن حقول JSON.

# Data to be inserted
data = [
  {
      "metadata": {"category": "electronics", "price": 99.99, "brand": "BrandA"},
      "pk": 1,
      "embedding": [0.12, 0.34, 0.56]
  },
  {
      "metadata": {"category": "home_appliances", "price": 249.99, "brand": "BrandB"},
      "pk": 2,
      "embedding": [0.56, 0.78, 0.90]
  },
  {
      "metadata": {"category": "furniture", "price": 399.99, "brand": "BrandC"},
      "pk": 3,
      "embedding": [0.91, 0.18, 0.23]
  }
]

# Insert data into the collection
client.insert(
    collection_name="your_collection_name",
    data=data
)

import com.google.gson.Gson;
import com.google.gson.JsonObject;

import io.milvus.v2.service.vector.request.InsertReq;
import io.milvus.v2.service.vector.response.InsertResp;

List<JsonObject> rows = new ArrayList<>();
Gson gson = new Gson();
rows.add(gson.fromJson("{\"metadata\": {\"category\": \"electronics\", \"price\": 99.99, \"brand\": \"BrandA\"}, \"pk\": 1, \"embedding\": [0.1, 0.2, 0.3]}", JsonObject.class));
rows.add(gson.fromJson("{\"metadata\": {\"category\": \"home_appliances\", \"price\": 249.99, \"brand\": \"BrandB\"}, \"pk\": 2, \"embedding\": [0.4, 0.5, 0.6]}", JsonObject.class));
rows.add(gson.fromJson("{\"metadata\": {\"category\": \"furniture\", \"price\": 399.99, \"brand\": \"BrandC\"}, \"pk\": 3, \"embedding\": [0.7, 0.8, 0.9]}", JsonObject.class));

InsertResp insertR = client.insert(InsertReq.builder()
        .collectionName("my_json_collection")
        .data(rows)
        .build());

const data = [
  {
      "metadata": {"category": "electronics", "price": 99.99, "brand": "BrandA"},
      "pk": 1,
      "embedding": [0.12, 0.34, 0.56]
  },
  {
      "metadata": {"category": "home_appliances", "price": 249.99, "brand": "BrandB"},
      "pk": 2,
      "embedding": [0.56, 0.78, 0.90]
  },
  {
      "metadata": {"category": "furniture", "price": 399.99, "brand": "BrandC"},
      "pk": 3,
      "embedding": [0.91, 0.18, 0.23]
  }
]

client.insert({
    collection_name: "my_json_collection",
    data: data
});

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/insert" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
    "data": [
        {
            "metadata": {"category": "electronics", "price": 99.99, "brand": "BrandA"},
            "pk": 1,
            "embedding": [0.12, 0.34, 0.56]
        },
        {
            "metadata": {"category": "home_appliances", "price": 249.99, "brand": "BrandB"},
            "pk": 2,
            "embedding": [0.56, 0.78, 0.90]
        },
        {
            "metadata": {"category": "furniture", "price": 399.99, "brand": "BrandC"},
            "pk": 3,
            "embedding": [0.91, 0.18, 0.23]
        }       
    ],
    "collectionName": "my_json_collection"
}'

في هذا المثال

  • يتضمن كل إدخال بيانات حقلاً أساسيًا (pkmetadata كحقل JSON لتخزين معلومات مثل فئة المنتج والسعر والعلامة التجارية.

  • embedding حقل متجه ثلاثي الأبعاد يُستخدم للبحث عن تشابه المتجهات.

البحث والاستعلام

تسمح حقول JSON بالتصفية العددية أثناء عمليات البحث، مما يعزز قدرات البحث المتجهية في Milvus. يمكنك الاستعلام بناءً على خصائص JSON إلى جانب تشابه المتجهات.

تصفية الاستعلامات

يمكنك تصفية البيانات بناءً على خصائص JSON، مثل مطابقة قيم محددة أو التحقق مما إذا كان الرقم يقع ضمن نطاق معين.

filter = 'metadata["category"] == "electronics" and metadata["price"] < 150'

res = client.query(
    collection_name="my_json_collection",
    filter=filter,
    output_fields=["metadata"]
)

print(res)

# Output
# data: ["{'metadata': {'category': 'electronics', 'price': 99.99, 'brand': 'BrandA'}, 'pk': 1}"] 

import io.milvus.v2.service.vector.request.QueryReq;
import io.milvus.v2.service.vector.response.QueryResp;

String filter = "metadata[\"category\"] == \"electronics\" and metadata[\"price\"] < 150";
QueryResp resp = client.query(QueryReq.builder()
        .collectionName("my_json_collection")
        .filter(filter)
        .outputFields(Collections.singletonList("metadata"))
        .build());

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

// Output
//
// [QueryResp.QueryResult(entity={metadata={"category":"electronics","price":99.99,"brand":"BrandA"}, pk=1})]

client.query({
    collection_name: 'my_scalar_collection',
    filter: 'metadata["category"] == "electronics" and metadata["price"] < 150',
    output_fields: ['metadata']
});

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/query" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
    "collectionName": "my_json_collection",
    "filter": "metadata[\"category\"] == \"electronics\" and metadata[\"price\"] < 150",
    "outputFields": ["metadata"]
}'
{"code":0,"cost":0,"data":[{"metadata":"{\"category\": \"electronics\", \"price\": 99.99, \"brand\": \"BrandA\"}","pk":1}]}

في الاستعلام أعلاه، يقوم Milvus بتصفية الكيانات التي يكون فيها الحقل metadata فئة "electronics" وسعر أقل من 150، وإرجاع الكيانات التي تطابق هذه المعايير.

البحث المتجه مع تصفية JSON

من خلال الجمع بين تشابه المتجهات مع تصفية JSON، يمكنك التأكد من أن البيانات المسترجعة لا تتطابق دلاليًا فحسب، بل تفي أيضًا بشروط عمل محددة، مما يجعل نتائج البحث أكثر دقة وتوافقًا مع احتياجات المستخدم.

filter = 'metadata["brand"] == "BrandA"'

res = client.search(
    collection_name="my_json_collection",
    data=[[0.3, -0.6, 0.1]],
    limit=5,
    search_params={"params": {"nprobe": 10}},
    output_fields=["metadata"],
    filter=filter
)

print(res)

# Output
# data: ["[{'id': 1, 'distance': -0.2479381263256073, 'entity': {'metadata': {'category': 'electronics', 'price': 99.99, 'brand': 'BrandA'}}}]"] 

import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.response.SearchResp;

String filter = "metadata[\"brand\"] == \"BrandA\"";
SearchResp resp = client.search(SearchReq.builder()
        .collectionName("my_json_collection")
        .annsField("embedding")
        .data(Collections.singletonList(new FloatVec(new float[]{0.3f, -0.6f, 0.1f})))
        .topK(5)
        .outputFields(Collections.singletonList("metadata"))
        .filter(filter)
        .build());

System.out.println(resp.getSearchResults());

// Output
//
// [[SearchResp.SearchResult(entity={metadata={"category":"electronics","price":99.99,"brand":"BrandA"}}, score=-0.2364331, id=1)]]

client.search({
    collection_name: 'my_json_collection',
    data: [0.3, -0.6, 0.1],
    limit: 5,
    output_fields: ['metadata'],
    filter: 'metadata["category"] == "electronics" and metadata["price"] < 150',
});

curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
    "collectionName": "my_json_collection",
    "data": [
        [0.3, -0.6, 0.1]
    ],
    "annsField": "embedding",
    "limit": 5,
    "searchParams":{
        "params":{"nprobe":10}
    },
    "outputFields": ["metadata"],
    "filter": "metadata[\"brand\"] == \"BrandA\""
}'

## {"code":0,"cost":0,"data":[{"distance":-0.24793813,"id":1,"metadata":"{\"category\": \"electronics\", \"price\": 99.99, \"brand\": \"BrandA\"}"}]}

في هذا المثال، يقوم Milvus بإرجاع أفضل 5 كيانات الأكثر تشابهًا مع متجه الاستعلام، مع احتواء الحقل metadata على علامة تجارية "BrandA".

بالإضافة إلى ذلك، يدعم Milvus عوامل تصفية JSON المتقدمة مثل JSON_CONTAINS و JSON_CONTAINS_ALL و JSON_CONTAINS_ANY ، والتي يمكن أن تعزز قدرات الاستعلام بشكل أكبر. لمزيد من التفاصيل، راجع تصفية البيانات الوصفية.

الحدود

  • حدود الفهرسة: نظرًا لتعقيد هياكل البيانات، لا يتم دعم فهرسة حقول JSON.

  • مطابقة نوع البيانات: إذا كانت قيمة المفتاح لحقل JSON عبارة عن عدد صحيح أو نقطة عائمة، فلا يمكن مقارنتها إلا مع مفتاح آخر صحيح أو عائم أو INT32/64 أو FLOAT32/64. إذا كانت قيمة المفتاح سلسلة (VARCHAR)، فلا يمكن مقارنتها إلا مع مفتاح سلسلة آخر.

  • قيود التسمية: عند تسمية مفاتيح JSON، يوصى باستخدام الأحرف والأحرف الرقمية والأحرف السفلية فقط، لأن الأحرف الأخرى قد تسبب مشاكل أثناء التصفية أو البحث.

  • التعامل مع قيم السلسلة: بالنسبة لقيم السلسلة (VARCHAR)، يخزن Milvus سلاسل حقول JSON كما هي دون تحويل دلالي. على سبيل المثال 'a"b' "a'b" و 'a\\'b' و و "a\\"b" يتم تخزينها كما تم إدخالها ؛ ومع ذلك، 'a'b' و "a"b" تعتبر غير صالحة.

  • التعامل مع القواميس المتداخلة: يتم التعامل مع أي قواميس متداخلة داخل قيم حقول JSON على أنها سلاسل.

  • حد حجم حقل JSON: تقتصر حقول JSON على 65,536 بايت.

جرب Managed Milvus مجاناً

Zilliz Cloud خالي من المتاعب، ويعمل بواسطة Milvus ويعمل بسرعة 10 أضعاف.

ابدأ
التعليقات

هل كانت هذه الصفحة مفيدة؟