Bidang Angka
Bidang angka digunakan untuk menyimpan data numerik non-vektor di Milvus. Field ini biasanya digunakan untuk mendeskripsikan informasi tambahan yang berhubungan dengan data vektor, seperti usia, harga, dll. Dengan menggunakan data ini, Anda dapat mendeskripsikan vektor dengan lebih baik dan meningkatkan efisiensi pemfilteran data dan kueri bersyarat.
Bidang angka sangat berguna dalam banyak skenario. Misalnya, dalam rekomendasi e-commerce, bidang harga dapat digunakan untuk penyaringan; dalam analisis profil pengguna, rentang usia dapat membantu menyempurnakan hasil. Dikombinasikan dengan data vektor, kolom angka dapat membantu sistem menyediakan pencarian kemiripan sekaligus memenuhi kebutuhan pengguna yang dipersonalisasi dengan lebih tepat.
Jenis bidang angka yang didukung
Milvus mendukung berbagai jenis bidang angka untuk memenuhi kebutuhan penyimpanan data dan kueri yang berbeda.
Jenis | Deskripsi |
---|---|
| Tipe Boolean untuk menyimpan |
| Bilangan bulat 8-bit, cocok untuk menyimpan data bilangan bulat dengan rentang kecil. |
| Bilangan bulat 16-bit, untuk data bilangan bulat jarak menengah. |
| Bilangan bulat 32-bit, ideal untuk penyimpanan data bilangan bulat umum seperti jumlah produk atau ID pengguna. |
| Bilangan bulat 64-bit, cocok untuk menyimpan data jarak jauh seperti stempel waktu atau pengenal. |
| Angka floating-point 32-bit, untuk data yang membutuhkan presisi umum, seperti peringkat atau suhu. |
| Angka floating-point presisi ganda 64-bit, untuk data dengan presisi tinggi seperti informasi keuangan atau perhitungan ilmiah. |
Menambahkan bidang angka
Untuk menggunakan bidang angka di Milvus, tentukan bidang yang relevan dalam skema koleksi, atur datatype
ke jenis yang didukung seperti BOOL
atau INT8
. Untuk daftar lengkap jenis bidang angka yang didukung, lihat Jenis bidang angka yang didukung.
Contoh berikut ini menunjukkan cara mendefinisikan skema yang menyertakan bidang angka age
dan price
.
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="age", datatype=DataType.INT64)
schema.add_field(field_name="price", datatype=DataType.FLOAT)
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("age")
.dataType(DataType.Int64)
.build());
schema.addField(AddFieldReq.builder()
.fieldName("price")
.dataType(DataType.Float)
.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: "age",
data_type: DataType.Int64,
},
{
name: "price",
data_type: DataType.Float,
},
{
name: "pk",
data_type: DataType.Int64,
is_primary_key: true,
},
{
name: "embedding",
data_type: DataType.FloatVector,
dim: 3,
},
];
export int64Field='{
"fieldName": "age",
"dataType": "Int64"
}'
export floatField='{
"fieldName": "price",
"dataType": "Float"
}'
export pkField='{
"fieldName": "pk",
"dataType": "Int64",
"isPrimary": true
}'
export vectorField='{
"fieldName": "embedding",
"dataType": "FloatVector",
"elementTypeParams": {
"dim": 3
}
}'
export schema="{
\"autoID\": false,
\"fields\": [
$int64Field,
$floatField,
$pkField,
$vectorField
]
}"
Bidang utama dan bidang vektor wajib ada saat Anda membuat koleksi. Field utama mengidentifikasi setiap entitas secara unik, sedangkan field vektor sangat penting untuk pencarian kemiripan. Untuk lebih jelasnya, lihat Bidang Utama & AutoID, Vektor Padat, Vektor Biner, atau Vektor Jarang.
Mengatur parameter indeks
Menetapkan parameter indeks untuk bidang angka bersifat opsional, namun dapat meningkatkan efisiensi pencarian secara signifikan.
Pada contoh berikut, kami membuat AUTOINDEX
untuk bidang angka age
, yang memungkinkan Milvus secara otomatis membuat indeks yang sesuai berdasarkan tipe data. Untuk informasi lebih lanjut, lihat AUTOINDEX.
index_params = client.prepare_index_params()
index_params.add_index(
field_name="age",
index_type="AUTOINDEX",
index_name="inverted_index"
)
import io.milvus.v2.common.IndexParam;
import java.util.*;
List<IndexParam> indexes = new ArrayList<>();
indexes.add(IndexParam.builder()
.fieldName("age")
.indexType(IndexParam.IndexType.AUTOINDEX)
.build());
const indexParams = {
index_name: 'inverted_index',
field_name: 'age',
index_type: IndexType.AUTOINDEX,
);
export indexParams='[
{
"fieldName": "age",
"indexName": "inverted_index",
"indexType": "AUTOINDEX"
}
]'
Selain AUTOINDEX
, Anda dapat menentukan jenis indeks bidang angka lainnya. Untuk jenis indeks yang didukung, lihat Indeks Skalar.
Selain itu, sebelum membuat koleksi, Anda harus membuat indeks untuk bidang vektor. Dalam contoh ini, kita menggunakan AUTOINDEX
untuk menyederhanakan pengaturan indeks vektor.
# Add vector index
index_params.add_index(
field_name="embedding",
index_type="AUTOINDEX", # Use automatic indexing to simplify complex index settings
metric_type="COSINE" # Specify similarity metric type, options include L2, COSINE, or IP
)
indexes.add(IndexParam.builder()
.fieldName("embedding")
.indexType(IndexParam.IndexType.AUTOINDEX)
.metricType(IndexParam.MetricType.COSINE)
.build());
import { IndexType } from "@zilliz/milvus2-sdk-node";
const indexParams = [
{
field_name: "age",
index_name: "inverted_index",
index_type: IndexType.AUTOINDEX,
},
{
field_name: "embedding",
metric_type: "COSINE",
index_type: IndexType.AUTOINDEX,
},
];
export indexParams='[
{
"fieldName": "age",
"indexName": "inverted_index",
"indexType": "AUTOINDEX"
},
{
"fieldName": "embedding",
"metricType": "COSINE",
"indexType": "AUTOINDEX"
}
]'
Membuat koleksi
Setelah skema dan indeks ditentukan, Anda dapat membuat koleksi yang menyertakan field angka.
# Create Collection
client.create_collection(
collection_name="your_collection_name",
schema=schema,
index_params=index_params
)
CreateCollectionReq requestCreate = CreateCollectionReq.builder()
.collectionName("my_scalar_collection")
.collectionSchema(schema)
.indexParams(indexes)
.build();
client.createCollection(requestCreate);
client.create_collection({
collection_name: "my_scalar_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_scalar_collection\",
\"schema\": $schema,
\"indexParams\": $indexParams
}"
Menyisipkan data
Setelah membuat koleksi, Anda dapat menyisipkan data yang memiliki field angka.
data = [
{"age": 25, "price": 99.99, "pk": 1, "embedding": [0.1, 0.2, 0.3]},
{"age": 30, "price": 149.50, "pk": 2, "embedding": [0.4, 0.5, 0.6]},
{"age": 35, "price": 199.99, "pk": 3, "embedding": [0.7, 0.8, 0.9]},
]
client.insert(
collection_name="my_scalar_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("{\"age\": 25, \"price\": 99.99, \"pk\": 1, \"embedding\": [0.1, 0.2, 0.3]}", JsonObject.class));
rows.add(gson.fromJson("{\"age\": 30, \"price\": 149.50, \"pk\": 2, \"embedding\": [0.4, 0.5, 0.6]}", JsonObject.class));
rows.add(gson.fromJson("{\"age\": 35, \"price\": 199.99, \"pk\": 3, \"embedding\": [0.7, 0.8, 0.9]}", JsonObject.class));
InsertResp insertR = client.insert(InsertReq.builder()
.collectionName("my_scalar_collection")
.data(rows)
.build());
const data = [
{ age: 25, price: 99.99, pk: 1, embedding: [0.1, 0.2, 0.3] },
{ age: 30, price: 149.5, pk: 2, embedding: [0.4, 0.5, 0.6] },
{ age: 35, price: 199.99, pk: 3, embedding: [0.7, 0.8, 0.9] },
];
client.insert({
collection_name: "my_scalar_collection",
data: data,
});
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/insert" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"data": [
{"age": 25, "price": 99.99, "pk": 1, "embedding": [0.1, 0.2, 0.3]},
{"age": 30, "price": 149.50, "pk": 2, "embedding": [0.4, 0.5, 0.6]},
{"age": 35, "price": 199.99, "pk": 3, "embedding": [0.7, 0.8, 0.9]}
],
"collectionName": "my_scalar_collection"
}'
Pada contoh ini, kita memasukkan data yang mencakup age
, price
, pk
(field utama), dan representasi vektor (embedding
). Untuk memastikan bahwa data yang disisipkan sesuai dengan bidang yang didefinisikan dalam skema, disarankan untuk memeriksa tipe data terlebih dahulu untuk menghindari kesalahan.
Jika Anda menetapkan enable_dynamic_fields=True
ketika mendefinisikan skema, Milvus mengizinkan Anda untuk menyisipkan bidang angka yang tidak didefinisikan sebelumnya. Namun, perlu diingat bahwa hal ini dapat meningkatkan kompleksitas kueri dan manajemen, yang berpotensi mempengaruhi kinerja. Untuk informasi lebih lanjut, lihat Bidang Dinamis.
Pencarian dan kueri
Setelah menambahkan bidang angka, Anda dapat menggunakannya untuk pemfilteran dalam operasi pencarian dan kueri untuk mendapatkan hasil pencarian yang lebih tepat.
Menyaring kueri
Setelah menambahkan bidang angka, Anda dapat menggunakannya untuk pemfilteran dalam kueri. Misalnya, Anda dapat melakukan kueri untuk semua entitas di mana age
berada di antara 30 dan 40.
filter = "30 <= age <= 40"
res = client.query(
collection_name="my_scalar_collection",
filter=filter,
output_fields=["age","price"]
)
print(res)
# Output
# data: ["{'age': 30, 'price': np.float32(149.5), 'pk': 2}", "{'age': 35, 'price': np.float32(199.99), 'pk': 3}"]
import io.milvus.v2.service.vector.request.QueryReq;
import io.milvus.v2.service.vector.response.QueryResp;
String filter = "30 <= age <= 40";
QueryResp resp = client.query(QueryReq.builder()
.collectionName("my_scalar_collection")
.filter(filter)
.outputFields(Arrays.asList("age", "price"))
.build());
System.out.println(resp.getQueryResults());
// Output
//
// [QueryResp.QueryResult(entity={price=149.5, pk=2, age=30}), QueryResp.QueryResult(entity={price=199.99, pk=3, age=35})]
client.query({
collection_name: 'my_scalar_collection',
filter: '30 <= age <= 40',
output_fields: ['age', 'price']
});
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/query" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "my_scalar_collection",
"filter": "30 <= age <= 40",
"outputFields": ["age","price"]
}'
## {"code":0,"cost":0,"data":[{"age":30,"pk":2,"price":149.5},{"age":35,"pk":3,"price":199.99}]}
Ekspresi kueri ini mengembalikan semua entitas yang cocok dan mengeluarkan bidang age
dan price
. Untuk informasi lebih lanjut tentang kueri penyaringan, lihat Pemfilteran Metadata.
Pencarian vektor dengan pemfilteran angka
Selain pemfilteran bidang angka dasar, Anda dapat menggabungkan pencarian kemiripan vektor dengan pemfilteran bidang angka. Sebagai contoh, kode berikut ini menunjukkan cara menambahkan penyaring bidang angka ke pencarian vektor.
filter = "25 <= age <= 35"
res = client.search(
collection_name="my_scalar_collection",
data=[[0.3, -0.6, 0.1]],
limit=5,
search_params={"params": {"nprobe": 10}},
output_fields=["age","price"],
filter=filter
)
print(res)
# Output
# data: ["[{'id': 1, 'distance': -0.06000000238418579, 'entity': {'age': 25, 'price': 99.98999786376953}}, {'id': 2, 'distance': -0.12000000476837158, 'entity': {'age': 30, 'price': 149.5}}, {'id': 3, 'distance': -0.18000000715255737, 'entity': {'age': 35, 'price': 199.99000549316406}}]"]
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;
String filter = "25 <= age <= 35";
SearchResp resp = client.search(SearchReq.builder()
.collectionName("my_scalar_collection")
.annsField("embedding")
.data(Collections.singletonList(new FloatVec(new float[]{0.3f, -0.6f, 0.1f})))
.topK(5)
.outputFields(Arrays.asList("age", "price"))
.filter(filter)
.build());
System.out.println(resp.getSearchResults());
// Output
//
// [[SearchResp.SearchResult(entity={price=199.99, age=35}, score=-0.19054288, id=3), SearchResp.SearchResult(entity={price=149.5, age=30}, score=-0.20163085, id=2), SearchResp.SearchResult(entity={price=99.99, age=25}, score=-0.2364331, id=1)]]
client.search({
collection_name: 'my_scalar_collection',
data: [0.3, -0.6, 0.1],
limit: 5,
output_fields: ['age', 'price'],
filter: '25 <= age <= 35'
});
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "my_scalar_collection",
"data": [
[0.3, -0.6, 0.1]
],
"annsField": "embedding",
"limit": 5,
"outputFields": ["age", "price"]
}'
## {"code":0,"cost":0,"data":[{"age":35,"distance":-0.19054288,"id":3,"price":199.99},{"age":30,"distance":-0.20163085,"id":2,"price":149.5},{"age":25,"distance":-0.2364331,"id":1,"price":99.99}]}
Dalam contoh ini, pertama-tama kita mendefinisikan vektor kueri dan menambahkan kondisi filter 25 <= age <= 35
selama pencarian. Hal ini memastikan bahwa hasil pencarian tidak hanya mirip dengan vektor kueri tetapi juga memenuhi rentang usia yang ditentukan. Untuk informasi lebih lanjut, lihat Pemfilteran Metadata.