قابل للإلغاء والافتراضي
يسمح لك Milvus بتعيين السمة nullable والقيم الافتراضية للحقول القياسية، باستثناء الحقل الأساسي. بالنسبة للحقول التي تم وضع علامة nullable=True ، يمكنك تخطي الحقل عند إدراج البيانات، أو تعيينه مباشرة إلى قيمة فارغة، وسيتعامل النظام معه على أنه فارغ دون التسبب في حدوث خطأ. عندما يكون للحقل قيمة افتراضية، سيقوم النظام تلقائيًا بتطبيق هذه القيمة إذا لم يتم تحديد بيانات للحقل أثناء الإدراج.
تعمل القيمة الافتراضية والسمات القابلة للإلغاء على تبسيط عملية ترحيل البيانات من أنظمة قواعد البيانات الأخرى إلى ميلفوس من خلال السماح بمعالجة مجموعات البيانات ذات القيم الفارغة والحفاظ على إعدادات القيمة الافتراضية. عند إنشاء مجموعة، يمكنك أيضًا تمكين القيم القابلة للإلغاء أو تعيين قيم افتراضية للحقول التي قد تكون القيم فيها غير مؤكدة.
الحدود
تدعم الحقول العددية فقط، باستثناء الحقل الأساسي، القيم الافتراضية والسمة القابلة للإلغاء.
لا تدعم حقول JSON و Array القيم الافتراضية.
يمكن تكوين القيم الافتراضية أو السمة القابلة للإلغاء فقط أثناء إنشاء المجموعة ولا يمكن تعديلها بعد ذلك.
لا يمكن استخدام الحقول التي تم تمييزها على أنها قابلة للإلغاء كمفاتيح تقسيم. لمزيد من المعلومات حول مفاتيح التقسيم، راجع استخدام مفتاح التقسيم.
عند إنشاء فهرس على حقل قياسي مع تمكين السمة القابلة للفراغ، سيتم استبعاد القيم الفارغة من الفهرس.
حقول JSON و ARRAY: عند استخدام المشغلين
IS NULLأوIS NOT NULLللتصفية على حقول JSON أو ARRAY، يعمل هذان المشغلان على مستوى العمود، مما يشير إلى أنهما يقيمان فقط ما إذا كان كائن JSON أو المصفوفة بأكملها فارغة. على سبيل المثال، إذا كان أحد المفاتيح داخل كائن JSON فارغًا، فلن يتعرف عليه عامل التصفيةIS NULL. لمزيد من المعلومات، راجع المعاملات الأساسية.
سمة لاغية
تسمح لك السمة nullable بتخزين قيم فارغة في مجموعة، مما يوفر مرونة عند التعامل مع بيانات غير معروفة.
تعيين السمة لاغية
عند إنشاء مجموعة، استخدم nullable=True لتعريف الحقول القابلة للفراغ (الإعدادات الافتراضية إلى False). ينشئ المثال التالي مجموعة باسم my_collection ويضبط الحقل age على أنه قابل للإلغاء:
from pymilvus import MilvusClient, DataType
client = MilvusClient(uri='http://localhost:19530')
# Define collection schema
schema = client.create_schema(
auto_id=False,
enable_dynamic_schema=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)
schema.add_field(field_name="age", datatype=DataType.INT64, nullable=True) # Nullable field
# Set index params
index_params = client.prepare_index_params()
index_params.add_index(field_name="vector", index_type="AUTOINDEX", metric_type="L2")
# Create collection
client.create_collection(collection_name="my_collection", schema=schema, index_params=index_params)
import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.DataType;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
import java.util.*;
MilvusClientV2 client = new MilvusClientV2(ConnectConfig.builder()
.uri("http://localhost:19530")
.build());
CreateCollectionReq.CollectionSchema schema = client.createSchema();
schema.setEnableDynamicField(true);
schema.addField(AddFieldReq.builder()
.fieldName("id")
.dataType(DataType.Int64)
.isPrimaryKey(true)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("vector")
.dataType(DataType.FloatVector)
.dimension(5)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("age")
.dataType(DataType.Int64)
.isNullable(true)
.build());
List<IndexParam> indexes = new ArrayList<>();
Map<String,Object> extraParams = new HashMap<>();
indexes.add(IndexParam.builder()
.fieldName("vector")
.indexType(IndexParam.IndexType.AUTOINDEX)
.metricType(IndexParam.MetricType.L2)
.build());
CreateCollectionReq requestCreate = CreateCollectionReq.builder()
.collectionName("my_collection")
.collectionSchema(schema)
.indexParams(indexes)
.build();
client.createCollection(requestCreate);
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
const client = new MilvusClient({
address: "http://localhost:19530",
token: "root:Milvus",
});
await client.createCollection({
collection_name: "my_collection",
schema: [
{
name: "id",
is_primary_key: true,
data_type: DataType.int64,
},
{ name: "vector", data_type: DataType.Int64, dim: 5 },
{ name: "age", data_type: DataType.FloatVector, nullable: true },
],
index_params: [
{
index_name: "vector_inde",
field_name: "vector",
metric_type: MetricType.L2,
index_type: IndexType.AUTOINDEX,
},
],
});
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()
schema.WithField(entity.NewField().
WithName("id").
WithDataType(entity.FieldTypeInt64).
WithIsPrimaryKey(true),
).WithField(entity.NewField().
WithName("vector").
WithDataType(entity.FieldTypeFloatVector).
WithDim(5),
).WithField(entity.NewField().
WithName("age").
WithDataType(entity.FieldTypeInt64).
WithNullable(true),
)
indexOption := milvusclient.NewCreateIndexOption("my_collection", "vector",
index.NewAutoIndex(index.MetricType(entity.L2)))
err = client.CreateCollection(ctx,
milvusclient.NewCreateCollectionOption("my_collection", schema).
WithIndexOptions(indexOption))
if err != nil {
fmt.Println(err.Error())
// handle error
}
export pkField='{
"fieldName": "id",
"dataType": "Int64",
"isPrimary": true
}'
export vectorField='{
"fieldName": "vector",
"dataType": "FloatVector",
"elementTypeParams": {
"dim": 5
}
}'
export nullField='{
"fieldName": "age",
"dataType": "Int64",
"nullable": true
}'
export schema="{
\"autoID\": false,
\"fields\": [
$pkField,
$vectorField,
$nullField
]
}"
export indexParams='[
{
"fieldName": "vector",
"metricType": "L2",
"indexType": "AUTOINDEX"
}
]'
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d "{
\"collectionName\": \"my_collection\",
\"schema\": $schema,
\"indexParams\": $indexParams
}"
إدراج الكيانات
عندما تقوم بإدراج بيانات في حقل قابل للإلغاء، قم بإدراج بيانات لاغية أو احذف هذا الحقل مباشرةً:
data = [
{"id": 1, "vector": [0.1, 0.2, 0.3, 0.4, 0.5], "age": 30},
{"id": 2, "vector": [0.2, 0.3, 0.4, 0.5, 0.6], "age": None},
{"id": 3, "vector": [0.3, 0.4, 0.5, 0.6, 0.7]}
]
client.insert(collection_name="my_collection", 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("{\"id\": 1, \"vector\": [0.1, 0.2, 0.3, 0.4, 0.5], \"age\": 30}", JsonObject.class));
rows.add(gson.fromJson("{\"id\": 2, \"vector\": [0.2, 0.3, 0.4, 0.5, 0.6], \"age\": null}", JsonObject.class));
rows.add(gson.fromJson("{\"id\": 3, \"vector\": [0.3, 0.4, 0.5, 0.6, 0.7]}", JsonObject.class));
InsertResp insertR = client.insert(InsertReq.builder()
.collectionName("my_collection")
.data(rows)
.build());
const data = [
{ id: 1, vector: [0.1, 0.2, 0.3, 0.4, 0.5], age: 30 },
{ id: 2, vector: [0.2, 0.3, 0.4, 0.5, 0.6], age: null },
{ id: 3, vector: [0.3, 0.4, 0.5, 0.6, 0.7] },
];
client.insert({
collection_name: "my_collection",
data: data,
});
column, _ := column.NewNullableColumnInt64("age",
[]int64{30},
[]bool{true, false, false})
_, err = client.Insert(ctx, milvusclient.NewColumnBasedInsertOption("my_collection").
WithInt64Column("id", []int64{1, 2, 3}).
WithFloatVectorColumn("vector", 5, [][]float32{
{0.1, 0.2, 0.3, 0.4, 0.5},
{0.2, 0.3, 0.4, 0.5, 0.6},
{0.3, 0.4, 0.5, 0.6, 0.7},
}).
WithColumns(column),
)
if err != nil {
fmt.Println(err.Error())
// handle err
}
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/insert" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"data": [
{"id": 1, "vector": [0.1, 0.2, 0.3, 0.4, 0.5], "age": 30},
{"id": 2, "vector": [0.2, 0.3, 0.4, 0.5, 0.6], "age": null},
{"id": 3, "vector": [0.3, 0.4, 0.5, 0.6, 0.7]}
],
"collectionName": "my_collection"
}'
البحث والاستعلام بقيم فارغة
عند استخدام الطريقة search ، إذا كان الحقل يحتوي على قيم null ، ستُرجع نتيجة البحث الحقل على أنه فارغ:
res = client.search(
collection_name="my_collection",
data=[[0.1, 0.2, 0.4, 0.3, 0.128]],
limit=2,
search_params={"params": {"nprobe": 16}},
output_fields=["id", "age"]
)
print(res)
# Output
# data: ["[{'id': 1, 'distance': 0.15838398039340973, 'entity': {'age': 30, 'id': 1}}, {'id': 2, 'distance': 0.28278401494026184, 'entity': {'age': None, 'id': 2}}]"]
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp;
Map<String,Object> params = new HashMap<>();
params.put("nprobe", 16);
SearchResp resp = client.search(SearchReq.builder()
.collectionName("my_collection")
.annsField("vector")
.data(Collections.singletonList(new FloatVec(new float[]{0.1f, 0.2f, 0.3f, 0.4f, 0.5f})))
.topK(2)
.searchParams(params)
.outputFields(Arrays.asList("id", "age"))
.build());
System.out.println(resp.getSearchResults());
// Output
//
// [[SearchResp.SearchResult(entity={id=1, age=30}, score=0.0, id=1), SearchResp.SearchResult(entity={id=2, age=null}, score=0.050000004, id=2)]]
client.search({
collection_name: 'my_collection',
data: [0.3, -0.6, 0.1, 0.3, 0.5],
limit: 2,
output_fields: ['age', 'id'],
params: {
nprobe: 16
}
});
queryVector := []float32{0.1, 0.2, 0.4, 0.3, 0.128}
annParam := index.NewCustomAnnParam()
annParam.WithExtraParam("nprobe", 16)
resultSets, err := client.Search(ctx, milvusclient.NewSearchOption(
"my_collection", // collectionName
2, // limit
[]entity.Vector{entity.FloatVector(queryVector)},
).WithANNSField("vector").
WithAnnParam(annParam).
WithOutputFields("id", "age"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
for _, resultSet := range resultSets {
fmt.Println("IDs: ", resultSet.IDs.FieldData().GetScalars())
fmt.Println("Scores: ", resultSet.Scores)
fmt.Println("age: ", resultSet.GetColumn("age").FieldData().GetScalars())
}
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "my_collection",
"data": [
[0.1, -0.2, 0.3, 0.4, 0.5]
],
"annsField": "vector",
"limit": 2,
"outputFields": ["id", "age"]
}'
#{"code":0,"cost":0,"data":[{"age":30,"distance":0.16000001,"id":1},{"age":null,"distance":0.28999996,"id":2}]}
عند استخدام الأسلوب query للتصفية العددية، تكون نتائج التصفية للقيم الفارغة كلها خاطئة، مما يشير إلى أنه لن يتم تحديدها.
# Reviewing previously inserted data:
# {"id": 1, "vector": [0.1, 0.2, ..., 0.128], "age": 30}
# {"id": 2, "vector": [0.2, 0.3, ..., 0.129], "age": None}
# {"id": 3, "vector": [0.3, 0.4, ..., 0.130], "age": None} # Omitted age column is treated as None
results = client.query(
collection_name="my_collection",
filter="age >= 0",
output_fields=["id", "age"]
)
# Example output:
# [
# {"id": 1, "age": 30}
# ]
# Note: Entities with `age` as `null` (id 2 and 3) will not appear in the result.
import io.milvus.v2.service.vector.request.QueryReq;
import io.milvus.v2.service.vector.response.QueryResp;
QueryResp resp = client.query(QueryReq.builder()
.collectionName("my_collection")
.filter("age >= 0")
.outputFields(Arrays.asList("id", "age"))
.build());
System.out.println(resp.getQueryResults());
// Output
//
// [QueryResp.QueryResult(entity={id=1, age=30})]
const results = await client.query(
collection_name: "my_collection",
filter: "age >= 0",
output_fields: ["id", "age"]
);
resultSet, err := client.Query(ctx, milvusclient.NewQueryOption("my_collection").
WithFilter("age >= 0").
WithOutputFields("id", "age"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
fmt.Println("id: ", resultSet.GetColumn("id").FieldData().GetScalars())
fmt.Println("age: ", resultSet.GetColumn("age").FieldData().GetScalars())
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/query" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "my_collection",
"filter": "age >= 0",
"outputFields": ["id", "age"]
}'
# {"code":0,"cost":0,"data":[{"age":30,"id":1}]}
لإرجاع كيانات بقيم null ، قم بالاستعلام بدون أي شرط تصفية عددية على النحو التالي:
يقوم الأسلوب query ، عند استخدامه بدون أي شروط تصفية، باسترجاع جميع الكيانات في المجموعة، بما في ذلك الكيانات ذات القيم الفارغة. لتقييد عدد الكيانات التي تم إرجاعها، يجب تحديد المعلمة limit.
null_results = client.query(
collection_name="my_collection",
filter="", # Query without any filtering condition
output_fields=["id", "age"],
limit=10
)
# Example output:
# [{"id": 2, "age": None}, {"id": 3, "age": None}]
QueryResp resp = client.query(QueryReq.builder()
.collectionName("my_collection")
.filter("")
.outputFields(Arrays.asList("id", "age"))
.limit(10)
.build());
System.out.println(resp.getQueryResults());
const results = await client.query(
collection_name: "my_collection",
filter: "",
output_fields: ["id", "age"],
limit: 10
);
resultSet, err = client.Query(ctx, milvusclient.NewQueryOption("my_collection").
WithFilter("").
WithLimit(10).
WithOutputFields("id", "age"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
fmt.Println("id: ", resultSet.GetColumn("id"))
fmt.Println("age: ", resultSet.GetColumn("age"))
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/query" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "my_collection",
"expr": "",
"outputFields": ["id", "age"],
"limit": 10
}'
# {"code":0,"cost":0,"data":[{"age":30,"id":1},{"age":null,"id":2},{"age":null,"id":3}]}
القيم الافتراضية
القيم الافتراضية هي قيم محددة مسبقًا للحقول العددية. إذا لم تقم بتوفير قيمة لحقل بقيم افتراضية أثناء الإدراج، يستخدم النظام تلقائيًا القيمة الافتراضية.
تعيين القيم الافتراضية
عند إنشاء مجموعة، استخدم المعلمة default_value لتحديد القيمة الافتراضية للحقل. يوضح المثال التالي كيفية تعيين القيمة الافتراضية age إلى 18 و status إلى "active":
schema = client.create_schema(
auto_id=False,
enable_dynamic_schema=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)
schema.add_field(field_name="age", datatype=DataType.INT64, default_value=18)
schema.add_field(field_name="status", datatype=DataType.VARCHAR, default_value="active", max_length=10)
index_params = client.prepare_index_params()
index_params.add_index(field_name="vector", index_type="AUTOINDEX", metric_type="L2")
client.create_collection(collection_name="my_collection", schema=schema, index_params=index_params)
import io.milvus.v2.common.DataType;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
import java.util.*;
CreateCollectionReq.CollectionSchema schema = client.createSchema();
schema.setEnableDynamicField(true);
schema.addField(AddFieldReq.builder()
.fieldName("id")
.dataType(DataType.Int64)
.isPrimaryKey(true)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("vector")
.dataType(DataType.FloatVector)
.dimension(5)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("age")
.dataType(DataType.Int64)
.defaultValue(18L)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("status")
.dataType(DataType.VarChar)
.maxLength(10)
.defaultValue("active")
.build());
List<IndexParam> indexes = new ArrayList<>();
Map<String,Object> extraParams = new HashMap<>();
indexes.add(IndexParam.builder()
.fieldName("vector")
.indexType(IndexParam.IndexType.AUTOINDEX)
.metricType(IndexParam.MetricType.L2)
.build());
CreateCollectionReq requestCreate = CreateCollectionReq.builder()
.collectionName("my_collection")
.collectionSchema(schema)
.indexParams(indexes)
.build();
client.createCollection(requestCreate);
import { MilvusClient, DataType } from "@zilliz/milvus2-sdk-node";
const client = new MilvusClient({
address: "http://localhost:19530",
token: "root:Milvus",
});
await client.createCollection({
collection_name: "my_collection",
schema: [
{
name: "id",
is_primary_key: true,
data_type: DataType.int64,
},
{ name: "vector", data_type: DataType.FloatVector, dim: 5 },
{ name: "age", data_type: DataType.Int64, default_value: 18 },
{ name: 'status', data_type: DataType.VarChar, max_length: 30, default_value: 'active'},
],
index_params: [
{
index_name: "vector_inde",
field_name: "vector",
metric_type: MetricType.L2,
index_type: IndexType.AUTOINDEX,
},
],
});
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
}
schema := entity.NewSchema()
schema.WithField(entity.NewField().
WithName("id").
WithDataType(entity.FieldTypeInt64).
WithIsPrimaryKey(true),
).WithField(entity.NewField().
WithName("vector").
WithDataType(entity.FieldTypeFloatVector).
WithDim(5),
).WithField(entity.NewField().
WithName("age").
WithDataType(entity.FieldTypeInt64).
WithDefaultValueLong(18),
).WithField(entity.NewField().
WithName("status").
WithDataType(entity.FieldTypeVarChar).
WithMaxLength(10).
WithDefaultValueString("active"),
)
indexOption := milvusclient.NewCreateIndexOption("my_collection", "vector",
index.NewAutoIndex(index.MetricType(entity.L2)))
err = client.CreateCollection(ctx,
milvusclient.NewCreateCollectionOption("my_collection", schema).
WithIndexOptions(indexOption))
if err != nil {
fmt.Println(err.Error())
// handle error
}
export pkField='{
"fieldName": "id",
"dataType": "Int64",
"isPrimary": true
}'
export vectorField='{
"fieldName": "vector",
"dataType": "FloatVector",
"elementTypeParams": {
"dim": 5
}
}'
export defaultValueField1='{
"fieldName": "age",
"dataType": "Int64",
"defaultValue": 18
}'
export defaultValueField2='{
"fieldName": "status",
"dataType": "VarChar",
"defaultValue": "active",
"elementTypeParams": {
"max_length": 10
}
}'
export schema="{
\"autoID\": false,
\"fields\": [
$pkField,
$vectorField,
$defaultValueField1,
$defaultValueField2
]
}"
export indexParams='[
{
"fieldName": "vector",
"metricType": "L2",
"indexType": "AUTOINDEX"
}
]'
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/collections/create" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d "{
\"collectionName\": \"my_collection\",
\"schema\": $schema,
\"indexParams\": $indexParams
}"
إدراج الكيانات
عند إدراج البيانات، إذا حذفت الحقول ذات القيمة الافتراضية أو عيّنت قيمتها إلى لا شيء، يستخدم النظام القيمة الافتراضية:
data = [
{"id": 1, "vector": [0.1, 0.2, ..., 0.128], "age": 30, "status": "premium"},
{"id": 2, "vector": [0.2, 0.3, ..., 0.129]}, # `age` and `status` use default values
{"id": 3, "vector": [0.3, 0.4, ..., 0.130], "age": 25, "status": None}, # `status` uses default value
{"id": 4, "vector": [0.4, 0.5, ..., 0.131], "age": None, "status": "inactive"} # `age` uses default value
]
client.insert(collection_name="my_collection", 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("{\"id\": 1, \"vector\": [0.1, 0.2, 0.3, 0.4, 0.5], \"age\": 30, \"status\": \"premium\"}", JsonObject.class));
rows.add(gson.fromJson("{\"id\": 2, \"vector\": [0.2, 0.3, 0.4, 0.5, 0.6]}", JsonObject.class));
rows.add(gson.fromJson("{\"id\": 3, \"vector\": [0.3, 0.4, 0.5, 0.6, 0.7], \"age\": 25, \"status\": null}", JsonObject.class));
rows.add(gson.fromJson("{\"id\": 4, \"vector\": [0.4, 0.5, 0.6, 0.7, 0.8], \"age\": null, \"status\": \"inactive\"}", JsonObject.class));
InsertResp insertR = client.insert(InsertReq.builder()
.collectionName("my_collection")
.data(rows)
.build());
const data = [
{"id": 1, "vector": [0.1, 0.2, 0.3, 0.4, 0.5], "age": 30, "status": "premium"},
{"id": 2, "vector": [0.2, 0.3, 0.4, 0.5, 0.6]},
{"id": 3, "vector": [0.3, 0.4, 0.5, 0.6, 0.7], "age": 25, "status": null},
{"id": 4, "vector": [0.4, 0.5, 0.6, 0.7, 0.8], "age": null, "status": "inactive"}
];
client.insert({
collection_name: "my_collection",
data: data,
});
column1, _ := column.NewNullableColumnInt64("age",
[]int64{30, 25},
[]bool{true, false, true, false})
column2, _ := column.NewNullableColumnVarChar("status",
[]string{"premium", "inactive"},
[]bool{true, false, false, true})
_, err = client.Insert(ctx, milvusclient.NewColumnBasedInsertOption("my_collection").
WithInt64Column("id", []int64{1, 2, 3, 4}).
WithFloatVectorColumn("vector", 5, [][]float32{
{0.1, 0.2, 0.3, 0.4, 0.5},
{0.2, 0.3, 0.4, 0.5, 0.6},
{0.3, 0.4, 0.5, 0.6, 0.7},
{0.4, 0.5, 0.6, 0.7, 0.8},
}).
WithColumns(column1, column2),
)
if err != nil {
fmt.Println(err.Error())
// handle err
}
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/insert" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"data": [
{"id": 1, "vector": [0.1, 0.2, 0.3, 0.4, 0.5], "age": 30, "status": "premium"},
{"id": 2, "vector": [0.2, 0.3, 0.4, 0.5, 0.6]},
{"id": 3, "vector": [0.3, 0.4, 0.5, 0.6, 0.7], "age": 25, "status": null},
{"id": 4, "vector": [0.4, 0.5, 0.6, 0.7, 0.8], "age": null, "status": "inactive"}
],
"collectionName": "my_collection"
}'
لمزيد من المعلومات حول كيفية تفعيل إعدادات القيمة الفارغة والافتراضية، راجع القواعد القابلة للتطبيق.
البحث والاستعلام بالقيم الافتراضية
يتم التعامل مع الكيانات التي تحتوي على قيم افتراضية مثل أي كيانات أخرى أثناء عمليات البحث المتجه والتصفية القياسية. يمكنك تضمين القيم الافتراضية كجزء من عمليات search و query الخاصة بك.
على سبيل المثال، في عملية search ، سيتم تضمين الكيانات التي تحتوي على age على القيمة الافتراضية 18 في النتائج:
res = client.search(
collection_name="my_collection",
data=[[0.1, 0.2, 0.4, 0.3, 0.5]],
search_params={"params": {"nprobe": 16}},
filter="age == 18", # 18 is the default value of the `age` field
limit=10,
output_fields=["id", "age", "status"]
)
print(res)
# Output
# data: ["[{'id': 2, 'distance': 0.050000004, 'entity': {'id': 2, 'age': 18, 'status': 'active'}}, {'id': 4, 'distance': 0.45000002, 'entity': {'id': 4, 'age': 18, 'status': 'inactive'}}]"]
import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.data.FloatVec;
import io.milvus.v2.service.vector.response.SearchResp;
Map<String,Object> params = new HashMap<>();
params.put("nprobe", 16);
SearchResp resp = client.search(SearchReq.builder()
.collectionName("my_collection")
.annsField("vector")
.data(Collections.singletonList(new FloatVec(new float[]{0.1f, 0.2f, 0.3f, 0.4f, 0.5f})))
.searchParams(params)
.filter("age == 18")
.topK(10)
.outputFields(Arrays.asList("id", "age", "status"))
.build());
System.out.println(resp.getSearchResults());
// Output
//
// [[SearchResp.SearchResult(entity={id=2, age=18, status=active}, score=0.050000004, id=2), SearchResp.SearchResult(entity={id=4, age=18, status=inactive}, score=0.45000002, id=4)]]
client.search({
collection_name: 'my_collection',
data: [0.3, -0.6, 0.1, 0.3, 0.5],
limit: 2,
output_fields: ['age', 'id', 'status'],
filter: 'age == 18',
params: {
nprobe: 16
}
});
queryVector := []float32{0.1, 0.2, 0.4, 0.3, 0.5}
annParam := index.NewCustomAnnParam()
annParam.WithExtraParam("nprobe", 16)
resultSets, err := client.Search(ctx, milvusclient.NewSearchOption(
"my_collection", // collectionName
10, // limit
[]entity.Vector{entity.FloatVector(queryVector)},
).WithANNSField("vector").
WithFilter("age == 18").
WithAnnParam(annParam).
WithOutputFields("id", "age", "status"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
for _, resultSet := range resultSets {
fmt.Println("IDs: ", resultSet.IDs.FieldData().GetScalars())
fmt.Println("Scores: ", resultSet.Scores)
fmt.Println("age: ", resultSet.GetColumn("age").FieldData().GetScalars())
fmt.Println("status: ", resultSet.GetColumn("status").FieldData().GetScalars())
}
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "my_collection",
"data": [
[0.1, 0.2, 0.3, 0.4, 0.5]
],
"annsField": "vector",
"limit": 10,
"filter": "age == 18",
"outputFields": ["id", "age", "status"]
}'
# {"code":0,"cost":0,"data":[{"age":18,"distance":0.050000004,"id":2,"status":"active"},{"age":18,"distance":0.45000002,"id":4,"status":"inactive"}]}
في عملية query ، يمكنك المطابقة أو التصفية حسب القيم الافتراضية مباشرةً:
# Query all entities where `age` equals the default value (18)
default_age_results = client.query(
collection_name="my_collection",
filter="age == 18",
output_fields=["id", "age", "status"]
)
# Query all entities where `status` equals the default value ("active")
default_status_results = client.query(
collection_name="my_collection",
filter='status == "active"',
output_fields=["id", "age", "status"]
)
import io.milvus.v2.service.vector.request.QueryReq;
import io.milvus.v2.service.vector.response.QueryResp;
QueryResp ageResp = client.query(QueryReq.builder()
.collectionName("my_collection")
.filter("age == 18")
.outputFields(Arrays.asList("id", "age", "status"))
.build());
System.out.println(ageResp.getQueryResults());
// Output
//
// [QueryResp.QueryResult(entity={id=2, age=18, status=active}), QueryResp.QueryResult(entity={id=4, age=18, status=inactive})]
QueryResp statusResp = client.query(QueryReq.builder()
.collectionName("my_collection")
.filter("status == \"active\"")
.outputFields(Arrays.asList("id", "age", "status"))
.build());
System.out.println(statusResp.getQueryResults());
// Output
//
// [QueryResp.QueryResult(entity={id=2, age=18, status=active}), QueryResp.QueryResult(entity={id=3, age=25, status=active})]
// Query all entities where `age` equals the default value (18)
const default_age_results = await client.query(
collection_name: "my_collection",
filter: "age == 18",
output_fields: ["id", "age", "status"]
);
// Query all entities where `status` equals the default value ("active")
const default_status_results = await client.query(
collection_name: "my_collection",
filter: 'status == "active"',
output_fields: ["id", "age", "status"]
)
resultSet, err := client.Query(ctx, milvusclient.NewQueryOption("my_collection").
WithFilter("age == 18").
WithOutputFields("id", "age", "status"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
fmt.Println("id: ", resultSet.GetColumn("id").FieldData().GetScalars())
fmt.Println("age: ", resultSet.GetColumn("age").FieldData().GetScalars())
fmt.Println("status: ", resultSet.GetColumn("status").FieldData().GetScalars())
resultSet, err = client.Query(ctx, milvusclient.NewQueryOption("my_collection").
WithFilter("status == \"active\"").
WithOutputFields("id", "age", "status"))
if err != nil {
fmt.Println(err.Error())
// handle error
}
fmt.Println("id: ", resultSet.GetColumn("id").FieldData().GetScalars())
fmt.Println("age: ", resultSet.GetColumn("age").FieldData().GetScalars())
fmt.Println("status: ", resultSet.GetColumn("status").FieldData().GetScalars())
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/query" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "my_collection",
"filter": "age == 18",
"outputFields": ["id", "age", "status"]
}'
# {"code":0,"cost":0,"data":[{"age":18,"id":2,"status":"active"},{"age":18,"id":4,"status":"inactive"}]}
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/query" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
--header "Request-Timeout: 10" \
-d '{
"collectionName": "my_collection",
"filter": "status == \"active\"",
"outputFields": ["id", "age", "status"]
}'
# {"code":0,"cost":0,"data":[{"age":18,"id":2,"status":"active"},{"age":25,"id":3,"status":"active"}]}
القواعد المطبقة
يلخّص الجدول التالي سلوك الأعمدة القابلة للإلغاء والقيم الافتراضية ضمن مجموعات تكوين مختلفة. تحدد هذه القواعد كيفية تعامل Milvus مع البيانات عند محاولة إدراج قيم فارغة أو إذا لم يتم توفير قيم الحقل.
قابل للفراغ |
القيمة الافتراضية |
نوع القيمة الافتراضية |
إدخال المستخدم |
النتيجة |
مثال |
|---|---|---|---|---|---|
✅ |
✅ |
غير فارغة |
لا شيء/لاغية |
يستخدم القيمة الافتراضية |
الحقل: إدخال المستخدم: فارغة النتيجة: يتم تخزينها كـ |
✅ |
❌ |
- |
لا شيء / فارغ |
مخزنة على أنها لاغية |
الحقل: إدخال المستخدم: فارغ النتيجة: مخزنة كقيمة لاغية |
❌ |
✅ |
غير فارغة |
لا شيء/لاغية |
يستخدم القيمة الافتراضية |
الحقل: إدخال المستخدم: فارغة النتيجة: مخزنة كـ |
❌ |
❌ |
- |
لا شيء / فارغ |
يلقي خطأ |
الحقل: إدخال المستخدم: فارغ النتيجة: العملية مرفوضة، يقوم النظام بإلقاء خطأ |
❌ |
✅ |
فارغة |
لا شيء / لاغية |
يلقي خطأ |
الحقل: إدخال المستخدم: فارغ النتيجة: العملية مرفوضة، يقوم النظام بإلقاء خطأ |