تمكين الحقل الديناميكي
تشرح هذه الصفحة كيفية استخدام الحقل الديناميكي في مجموعة لإدراج البيانات واسترجاعها بشكل مرن.
نظرة عامة
يسمح لك Milvus بتعريف مخطط مجموعة من خلال تعيين الاسم ونوع البيانات لكل حقل محدد بحيث يمكنك إنشاء فهارس في هذه الحقول لتحسين أداء البحث.
بمجرد تحديد الحقل، تحتاج إلى تضمين هذا الحقل عند إدراج البيانات. ماذا لو لم تكن بعض الحقول موجودة دائمًا في جميع إدخالات بياناتك؟ هنا يأتي دور الحقل الديناميكي.
الحقل الديناميكي في المجموعة هو حقل JSON محجوز يسمى $meta. يمكن أن يحتوي على حقول غير محددة بشكل منهجي وقيمها كأزواج مفاتيح-قيم. باستخدام الحقل الديناميكي، يمكنك البحث والاستعلام عن كل من الحقول المعرفة بالمخطط وأي حقول غير معرفة بالمخطط قد تحتوي على حقول غير معرفة بالمخطط.
تمكين الحقل الديناميكي
عند تحديد مخطط لمجموعة، يمكنك تعيين enable_dynamic_field إلى True لتمكين الحقل الديناميكي المحجوز، مما يشير إلى أن أي حقول غير معرفة من قبل المخطط وقيمها التي يتم إدراجها لاحقًا سيتم حفظها كأزواج قيمة مفتاح في الحقل الديناميكي المحجوز.
ينشئ المقتطف التالي مجموعة بحقلين معرّفين من قبل المخطط، وهما المعرف والمتجه، ويمكّن الحقل الديناميكي.
لمزيد من المعلومات حول المعلمات، راجع create_collection() في مرجع SDK.
للمزيد من المعلومات عن المعلمات، ارجع إلى createCollection() في مرجع SDK.
لمزيد من المعلومات عن المعلمات، ارجع إلى createCollection() في مرجع SDK.
import random, time
from pymilvus import connections, MilvusClient, DataType
SERVER_ADDR = "http://localhost:19530"
# 1. Set up a Milvus client
client = MilvusClient(
uri=SERVER_ADDR
)
# 2. Create a collection
schema = MilvusClient.create_schema(
auto_id=False,
enable_dynamic_field=True,
)
schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)
schema.add_field(field_name="vector", datatype=DataType.FLOAT_VECTOR, dim=5)
index_params = MilvusClient.prepare_index_params()
index_params.add_index(
field_name="id",
index_type="STL_SORT"
)
index_params.add_index(
field_name="vector",
index_type="IVF_FLAT",
metric_type="L2",
params={"nlist": 1024}
)
client.create_collection(
collection_name="test_collection",
schema=schema,
index_params=index_params
)
res = client.get_load_state(
collection_name="test_collection"
)
print(res)
# Output
#
# {
# "state": "<LoadState: Loaded>"
# }
import com.google.gson.Gson;
import com.google.gson.JsonObject;
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.vector.request.*;
import io.milvus.v2.service.vector.request.data.*;
import io.milvus.v2.service.vector.response.*;
import java.util.*;
String CLUSTER_ENDPOINT = "http://localhost:19530";
// 1. Connect to Milvus server
ConnectConfig connectConfig = ConnectConfig.builder()
.uri(CLUSTER_ENDPOINT)
.build();
MilvusClientV2 client = new MilvusClientV2(connectConfig);
// 2. Create a collection in customized setup mode
// 2.1 Create schema
CreateCollectionReq.CollectionSchema schema = client.createSchema();
schema.setEnableDynamicField(true);
// 2.2 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());
// 2.3 Prepare index parameters
IndexParam indexParamForIdField = IndexParam.builder()
.fieldName("id")
.indexType(IndexParam.IndexType.STL_SORT)
.build();
Map<String, Object> params = new HashMap<>();
params.put("nlist", 1024);
IndexParam indexParamForVectorField = IndexParam.builder()
.fieldName("vector")
.indexType(IndexParam.IndexType.IVF_FLAT)
.metricType(IndexParam.MetricType.IP)
.extraParams(params)
.build();
List<IndexParam> indexParams = new ArrayList<>();
indexParams.add(indexParamForIdField);
indexParams.add(indexParamForVectorField);
// 2.4 Create a collection with schema and index parameters
CreateCollectionReq customizedSetupReq = CreateCollectionReq.builder()
.collectionName("customized_setup")
.collectionSchema(schema)
.indexParams(indexParams)
.build();
client.createCollection(customizedSetupReq);
Thread.sleep(5000);
// 2.5 Get load state of the collection
GetLoadStateReq customSetupLoadStateReq1 = GetLoadStateReq.builder()
.collectionName("customized_setup")
.build();
boolean res = client.getLoadState(customSetupLoadStateReq1);
System.out.println(res);
// Output:
// true
const { MilvusClient, DataType, sleep } = require("@zilliz/milvus2-sdk-node")
const address = "http://localhost:19530"
async function main() {
// 1. Set up a Milvus Client
client = new MilvusClient({address});
// 2. Create a collection
// 2.1 Define fields
const fields = [
{
name: "id",
data_type: DataType.Int64,
is_primary_key: true,
auto_id: false
},
{
name: "vector",
data_type: DataType.FloatVector,
dim: 5
},
]
// 2.2 Prepare index parameters
const index_params = [{
field_name: "id",
index_type: "STL_SORT"
},{
field_name: "vector",
index_type: "IVF_FLAT",
metric_type: "IP",
params: { nlist: 1024}
}]
// 2.3 Create a collection with fields and index parameters
res = await client.createCollection({
collection_name: "test_collection",
fields: fields,
index_params: index_params,
enable_dynamic_field: true
})
console.log(res.error_code)
// Output
//
// Success
//
res = await client.getLoadState({
collection_name: "test_collection",
})
console.log(res.state)
// Output
//
// LoadStateLoaded
//
إدراج بيانات ديناميكية
بمجرد إنشاء المجموعة، يمكنك البدء في إدراج البيانات، بما في ذلك البيانات الديناميكية في المجموعة.
إعداد البيانات
في هذا القسم، تحتاج إلى إعداد بعض البيانات التي تم إنشاؤها عشوائيًا لإدراجها لاحقًا.
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)
data.append({
"id": i,
"vector": [ random.uniform(-1, 1) for _ in range(5) ],
"color": current_color,
"tag": current_tag,
"color_tag": f"{current_color}_{str(current_tag)}"
})
print(data[0])
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));
int current_tag = rand.nextInt(8999) + 1000;
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("tag", current_tag);
row.addProperty("color_tag", current_color + "_" + (rand.nextInt(8999) + 1000));
data.add(row);
}
System.out.println(data.get(0).toString());
const colors = ["green", "blue", "yellow", "red", "black", "white", "purple", "pink", "orange", "brown", "grey"]
var 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)
data.push({
id: i,
vector: [Math.random(), Math.random(), Math.random(), Math.random(), Math.random()],
color: current_color,
tag: current_tag,
color_tag: `${current_color}_${current_tag}`
})
}
console.log(data[0])
يمكنك عرض بنية البيانات التي تم إنشاؤها عن طريق التحقق من الإدخال الأول.
{
id: 0,
vector: [
0.1275656405044483,
0.47417858592773277,
0.13858264437643286,
0.2390904907020377,
0.8447862593689635
],
color: 'blue',
tag: 2064,
color_tag: 'blue_2064'
}
إدراج البيانات
بعد ذلك يمكنك إدراج البيانات بأمان في المجموعة.
لمزيد من المعلومات حول المعلمات، راجع insert() في مرجع SDK.
لمزيد من المعلومات حول المعلمات، ارجع إلى insert() في مرجع SDK.
لمزيد من المعلومات حول المعلمات، ارجع إلى insert() في مرجع SDK.
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,
# "(990 more items hidden)"
# ]
# }
time.sleep(5)
// 3.1 Insert data into the collection
InsertReq insertReq = InsertReq.builder()
.collectionName("customized_setup")
.data(data)
.build();
InsertResp insertResp = client.insert(insertReq);
System.out.println(insertResp.getInsertCnt());
// Output:
// 1000
Thread.sleep(5000);
res = await client.insert({
collection_name: "test_collection",
data: data,
})
console.log(res.insert_cnt)
// Output
//
// 1000
//
await sleep(5000)
البحث باستخدام الحقول الديناميكية
إذا كنت قد أنشأت المجموعة مع تمكين الحقل الديناميكي وأدرجت حقولاً غير محددة بشكل مخطط، يمكنك استخدام هذه الحقول في تعبير التصفية للبحث أو الاستعلام كما يلي.
لمزيد من المعلومات حول المعلمات، راجع search() في مرجع SDK.
لمزيد من المعلومات حول المعلمات، ارجع إلى search() في مرجع SDK.
لمزيد من المعلومات حول المعلمات، ارجع إلى search() في مرجع SDK.
# 4. Search with dynamic fields
query_vectors = [[0.3580376395471989, -0.6023495712049978, 0.18414012509913835, -0.26286205330961354, 0.9029438446296592]]
res = client.search(
collection_name="test_collection",
data=query_vectors,
filter="color in [\"red\", \"green\"]",
search_params={"metric_type": "L2", "params": {"nprobe": 10}},
limit=3
)
print(res)
# Output
#
# [
# [
# {
# "id": 863,
# "distance": 0.188413605093956,
# "entity": {
# "id": 863,
# "color_tag": "red_2371"
# }
# },
# {
# "id": 799,
# "distance": 0.29188022017478943,
# "entity": {
# "id": 799,
# "color_tag": "red_2235"
# }
# },
# {
# "id": 564,
# "distance": 0.3492690920829773,
# "entity": {
# "id": 564,
# "color_tag": "red_9186"
# }
# }
# ]
# ]
// 4. Search with non-schema-defined fields
List<BaseVector> queryVectors = Collections.singletonList(new FloatVec(new float[]{0.3580376395471989f, -0.6023495712049978f, 0.18414012509913835f, -0.26286205330961354f, 0.9029438446296592f}));
SearchReq searchReq = SearchReq.builder()
.collectionName("customized_setup")
.data(queryVectors)
.filter("$meta[\"color\"] in [\"red\", \"green\"]")
.outputFields(Arrays.asList("id", "color_tag"))
.topK(3)
.build();
SearchResp searchResp = client.search(searchReq);
List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();
for (List<SearchResp.SearchResult> results : searchResults) {
System.out.println("TopK results:");
for (SearchResp.SearchResult result : results) {
System.out.println(result);
}
}
// Output:
// SearchResp.SearchResult(entity={color_tag=green_2205, id=556}, score=1.134007, id=556)
// SearchResp.SearchResult(entity={color_tag=red_2786, id=310}, score=0.9072295, id=310)
// SearchResp.SearchResult(entity={color_tag=red_9493, id=215}, score=0.8819287, id=215)
// 4. Search with non-schema-defined fields
const query_vectors = [[0.1, 0.2, 0.3, 0.4, 0.5]]
res = await client.search({
collection_name: "test_collection",
data: query_vectors,
filter: "color in [\"red\", \"green\"]",
output_fields: ["color_tag"],
limit: 3
})
console.log(res.results)
// Output
//
// [
// { score: 1.2284551858901978, id: '301', color_tag: 'red_1270' },
// { score: 1.2195171117782593, id: '205', color_tag: 'red_2780' },
// { score: 1.2055039405822754, id: '487', color_tag: 'red_6653' }
// ]
//
الملخصات
تجدر الإشارة إلى أن اللون والعلامة وعلامة اللون وعلامة اللون غير موجودة عند تعريف مخطط المجموعة، ولكن يمكنك استخدامها كحقول معرفة بالمخطط عند إجراء عمليات البحث والاستعلامات.
إذا كان اسم الحقل غير المعرف من قبل المخطط يحتوي على أحرف أخرى غير الأرقام والحروف والشرطات السفلية، مثل علامات الجمع (+) أو العلامات النجمية (*) أو علامات الدولار ()، يجب عليك تضمين المفتاح داخل __meta[]__ كما هو موضح في مقتطف الشيفرة التالي عند استخدامه في تعبير منطقي أو تضمينه في حقول الإخراج.
...
filter='$meta["$key"] in ["a", "b", "c"]',
output_fields='$meta["$key"]'
...