Pencocokan Teks
Pencocokan teks di Milvus memungkinkan pencarian dokumen yang tepat berdasarkan istilah tertentu. Fitur ini terutama digunakan untuk pencarian yang difilter untuk memenuhi kondisi tertentu dan dapat menggabungkan pemfilteran skalar untuk menyaring hasil kueri, sehingga memungkinkan pencarian kemiripan dalam vektor yang memenuhi kriteria skalar.
Pencocokan teks berfokus pada pencarian kemunculan yang tepat dari istilah kueri, tanpa menilai relevansi dokumen yang dicocokkan. Jika Anda ingin mengambil dokumen yang paling relevan berdasarkan makna semantik dan pentingnya istilah kueri, kami sarankan Anda menggunakan Pencarian Teks Lengkap.
Gambaran Umum
Milvus mengintegrasikan Tantivy untuk mendukung indeks terbalik yang mendasarinya dan pencarian teks berbasis istilah. Untuk setiap entri teks, Milvus mengindeksnya dengan mengikuti prosedur.
Penganalisis: Penganalisis memproses teks masukan dengan menokenya menjadi kata-kata individual, atau token, dan kemudian menerapkan filter sesuai kebutuhan. Hal ini memungkinkan Milvus untuk membangun indeks berdasarkan token-token ini.
Pengindeksan: Setelah analisis teks, Milvus membuat indeks terbalik yang memetakan setiap token unik ke dokumen yang mengandungnya.
Ketika pengguna melakukan pencocokan teks, indeks terbalik digunakan untuk mengambil semua dokumen yang mengandung istilah dengan cepat. Hal ini jauh lebih cepat daripada memindai setiap dokumen satu per satu.
Pencocokan Teks
Mengaktifkan pencocokan teks
Pencocokan teks bekerja pada tipe bidang VARCHAR
, yang pada dasarnya adalah tipe data string di Milvus. Untuk mengaktifkan pencocokan teks, setel enable_analyzer
dan enable_match
ke True
, lalu secara opsional konfigurasikan penganalisis untuk analisis teks ketika menentukan skema koleksi Anda.
Tetapkan enable_analyzer
dan enable_match
Untuk mengaktifkan pencocokan teks untuk bidang VARCHAR
tertentu, setel parameter enable_analyzer
dan enable_match
ke True
saat menentukan skema bidang. Ini menginstruksikan Milvus untuk melakukan tokenisasi teks dan membuat indeks terbalik untuk bidang yang ditentukan, sehingga memungkinkan pencocokan teks yang cepat dan efisien.
from pymilvus import MilvusClient, DataType
schema = MilvusClient.create_schema(auto_id=True, enable_dynamic_field=False)
schema.add_field(
field_name='text',
datatype=DataType.VARCHAR,
max_length=1000,
enable_analyzer=True, # Whether to enable text analysis for this field
enable_match=True # Whether to enable text match
)
import io.milvus.v2.common.DataType;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq;
CreateCollectionReq.CollectionSchema schema = CreateCollectionReq.CollectionSchema.builder()
.enableDynamicField(false)
.build();
schema.addField(AddFieldReq.builder()
.fieldName("text")
.dataType(DataType.VarChar)
.maxLength(1000)
.enableAnalyzer(true)
.enableMatch(true)
.build());
const schema = [
{
name: "id",
data_type: DataType.Int64,
is_primary_key: true,
},
{
name: "text",
data_type: "VarChar",
enable_analyzer: true,
enable_match: true,
max_length: 1000,
},
{
name: "sparse",
data_type: DataType.SparseFloatVector,
},
];
export schema='{
"autoId": true,
"enabledDynamicField": false,
"fields": [
{
"fieldName": "id",
"dataType": "Int64",
"isPrimary": true
},
{
"fieldName": "text",
"dataType": "VarChar",
"elementTypeParams": {
"max_length": 1000,
"enable_analyzer": true,
"enable_match": true
}
},
{
"fieldName": "sparse",
"dataType": "SparseFloatVector"
}
]
}'
Opsional: Mengonfigurasi penganalisis
Performa dan keakuratan pencocokan teks bergantung pada penganalisis yang dipilih. Penganalisis yang berbeda disesuaikan dengan berbagai bahasa dan struktur teks, sehingga memilih yang tepat dapat secara signifikan memengaruhi hasil pencarian untuk kasus penggunaan spesifik Anda.
Secara default, Milvus menggunakan standard
analyzer, yang menandai teks berdasarkan spasi dan tanda baca, menghapus token yang lebih panjang dari 40 karakter, dan mengubah teks menjadi huruf kecil. Tidak ada parameter tambahan yang diperlukan untuk menerapkan pengaturan default ini. Untuk informasi lebih lanjut, lihat Standar.
Jika diperlukan penganalisis yang berbeda, Anda dapat mengonfigurasinya menggunakan parameter analyzer_params
. Misalnya, untuk menerapkan penganalisis english
untuk memproses teks bahasa Inggris.
analyzer_params={
"type": "english"
}
schema.add_field(
field_name='text',
datatype=DataType.VARCHAR,
max_length=200,
enable_analyzer=True,
analyzer_params=analyzer_params,
enable_match=True,
)
Map<String, Object> analyzerParams = new HashMap<>();
analyzerParams.put("type", "english");
schema.addField(AddFieldReq.builder()
.fieldName("text")
.dataType(DataType.VarChar)
.maxLength(200)
.enableAnalyzer(true)
.analyzerParams(analyzerParams)
.enableMatch(true)
.build());
const schema = [
{
name: "id",
data_type: DataType.Int64,
is_primary_key: true,
},
{
name: "text",
data_type: "VarChar",
enable_analyzer: true,
enable_match: true,
max_length: 1000,
analyzer_params: { type: 'english' },
},
{
name: "sparse",
data_type: DataType.SparseFloatVector,
},
];
export schema='{
"autoId": true,
"enabledDynamicField": false,
"fields": [
{
"fieldName": "id",
"dataType": "Int64",
"isPrimary": true
},
{
"fieldName": "text",
"dataType": "VarChar",
"elementTypeParams": {
"max_length": 200,
"enable_analyzer": true,
"enable_match": true,
"analyzer_params": {"type": "english"}
}
},
{
"fieldName": "my_vector",
"dataType": "FloatVector",
"elementTypeParams": {
"dim": "5"
}
}
]
}'
Milvus juga menyediakan berbagai penganalisis lain yang cocok untuk berbagai bahasa dan skenario. Untuk lebih jelasnya, lihat Ikhtisar.
Menggunakan pencocokan teks
Setelah Anda mengaktifkan pencocokan teks untuk bidang VARCHAR di skema koleksi Anda, Anda dapat melakukan pencocokan teks menggunakan ekspresi TEXT_MATCH
.
Sintaks ekspresi TEXT_MATCH
Ekspresi TEXT_MATCH
digunakan untuk menentukan bidang dan istilah yang akan dicari. Sintaksnya adalah sebagai berikut.
TEXT_MATCH(field_name, text)
field_name
: Nama bidang VARCHAR yang akan dicari.text
: Istilah yang akan dicari. Beberapa istilah dapat dipisahkan dengan spasi atau pembatas lain yang sesuai berdasarkan bahasa dan penganalisis yang dikonfigurasi.
Secara default, TEXT_MATCH
menggunakan logika pencocokan OR, yang berarti akan mengembalikan dokumen yang mengandung salah satu istilah yang ditentukan. Sebagai contoh, untuk mencari dokumen yang mengandung istilah machine
atau deep
di bidang text
, gunakan ekspresi berikut.
filter = "TEXT_MATCH(text, 'machine deep')"
String filter = "TEXT_MATCH(text, 'machine deep')";
const filter = "TEXT_MATCH(text, 'machine deep')";
export filter="\"TEXT_MATCH(text, 'machine deep')\""
Anda juga dapat menggabungkan beberapa ekspresi TEXT_MATCH
menggunakan operator logika untuk melakukan pencocokan AND.
Untuk mencari dokumen yang mengandung
machine
dandeep
di bidangtext
, gunakan ekspresi berikut.filter = "TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'deep')"
String filter = "TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'deep')";
const filter = "TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'deep')"
export filter="\"TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'deep')\""
Untuk mencari dokumen yang mengandung
machine
danlearning
tetapi tanpadeep
di bidangtext
, gunakan ekspresi berikut:filter = "not TEXT_MATCH(text, 'deep') and TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'learning')"
String filter = "not TEXT_MATCH(text, 'deep') and TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'learning')";
const filter = "not TEXT_MATCH(text, 'deep') and TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'learning')";
export filter="\"not TEXT_MATCH(text, 'deep') and TEXT_MATCH(text, 'machine') and TEXT_MATCH(text, 'learning')\""
Mencari dengan pencocokan teks
Pencocokan teks dapat digunakan bersama dengan pencarian kemiripan vektor untuk mempersempit cakupan pencarian dan meningkatkan kinerja pencarian. Dengan memfilter koleksi menggunakan pencocokan teks sebelum pencarian kemiripan vektor, Anda dapat mengurangi jumlah dokumen yang perlu dicari, sehingga menghasilkan waktu kueri yang lebih cepat.
Dalam contoh ini, ekspresi filter
memfilter hasil pencarian untuk hanya menyertakan dokumen yang cocok dengan istilah yang ditentukan keyword1
atau keyword2
. Pencarian kemiripan vektor kemudian dilakukan pada subset dokumen yang telah difilter ini.
# Match entities with `keyword1` or `keyword2`
filter = "TEXT_MATCH(text, 'keyword1 keyword2')"
# Assuming 'embeddings' is the vector field and 'text' is the VARCHAR field
result = MilvusClient.search(
collection_name="YOUR_COLLECTION_NAME", # Your collection name
anns_field="embeddings", # Vector field name
data=[query_vector], # Query vector
filter=filter,
search_params={"params": {"nprobe": 10}},
limit=10, # Max. number of results to return
output_fields=["id", "text"] # Fields to return
)
String filter = "TEXT_MATCH(text, 'keyword1 keyword2')";
SearchResp searchResp = client.search(SearchReq.builder()
.collectionName("YOUR_COLLECTION_NAME")
.annsField("embeddings")
.data(Collections.singletonList(queryVector)))
.filter(filter)
.topK(10)
.outputFields(Arrays.asList("id", "text"))
.build());
// Match entities with `keyword1` or `keyword2`
const filter = "TEXT_MATCH(text, 'keyword1 keyword2')";
// Assuming 'embeddings' is the vector field and 'text' is the VARCHAR field
const result = await client.search(
collection_name: "YOUR_COLLECTION_NAME", // Your collection name
anns_field: "embeddings", // Vector field name
data: [query_vector], // Query vector
filter: filter,
params: {"nprobe": 10},
limit: 10, // Max. number of results to return
output_fields: ["id", "text"] //Fields to return
);
export filter="\"TEXT_MATCH(text, 'keyword1 keyword2')\""
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/search" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "demo2",
"annsField": "my_vector",
"data": [[0.19886812562848388, 0.06023560599112088, 0.6976963061752597, 0.2614474506242501, 0.838729485096104]],
"filter": '"$filter"',
"searchParams": {
"params": {
"nprobe": 10
}
},
"limit": 3,
"outputFields": ["text","id"]
}'
Kueri dengan pencocokan teks
Pencocokan teks juga dapat digunakan untuk pemfilteran skalar dalam operasi kueri. Dengan menetapkan ekspresi TEXT_MATCH
dalam parameter expr
dari metode query()
, Anda dapat mengambil dokumen yang cocok dengan istilah yang diberikan.
Contoh di bawah ini mengambil dokumen di mana bidang text
berisi kedua istilah keyword1
dan keyword2
.
# Match entities with both `keyword1` and `keyword2`
filter = "TEXT_MATCH(text, 'keyword1') and TEXT_MATCH(text, 'keyword2')"
result = MilvusClient.query(
collection_name="YOUR_COLLECTION_NAME",
filter=filter,
output_fields=["id", "text"]
)
String filter = "TEXT_MATCH(text, 'keyword1') and TEXT_MATCH(text, 'keyword2')";
QueryResp queryResp = client.query(QueryReq.builder()
.collectionName("YOUR_COLLECTION_NAME")
.filter(filter)
.outputFields(Arrays.asList("id", "text"))
.build()
);
// Match entities with both `keyword1` and `keyword2`
const filter = "TEXT_MATCH(text, 'keyword1') and TEXT_MATCH(text, 'keyword2')";
const result = await client.query(
collection_name: "YOUR_COLLECTION_NAME",
filter: filter,
output_fields: ["id", "text"]
)
export filter="\"TEXT_MATCH(text, 'keyword1') and TEXT_MATCH(text, 'keyword2')\""
export CLUSTER_ENDPOINT="http://localhost:19530"
export TOKEN="root:Milvus"
curl --request POST \
--url "${CLUSTER_ENDPOINT}/v2/vectordb/entities/query" \
--header "Authorization: Bearer ${TOKEN}" \
--header "Content-Type: application/json" \
-d '{
"collectionName": "demo2",
"filter": '"$filter"',
"outputFields": ["id", "text"]
}'
Pertimbangan
Mengaktifkan pencocokan teks untuk suatu bidang akan memicu pembuatan indeks terbalik, yang menghabiskan sumber daya penyimpanan. Pertimbangkan dampak penyimpanan ketika memutuskan untuk mengaktifkan fitur ini, karena bervariasi berdasarkan ukuran teks, token unik, dan penganalisis yang digunakan.
Setelah Anda mendefinisikan penganalisis dalam skema Anda, pengaturannya menjadi permanen untuk koleksi tersebut. Jika Anda memutuskan bahwa penganalisis yang berbeda lebih sesuai dengan kebutuhan Anda, Anda dapat mempertimbangkan untuk menghapus koleksi yang ada dan membuat koleksi baru dengan konfigurasi penganalisis yang diinginkan.
Aturan pelarian dalam ekspresi
filter
:- Karakter yang diapit oleh tanda kutip ganda atau tanda kutip tunggal di dalam ekspresi ditafsirkan sebagai konstanta string. Jika konstanta string menyertakan karakter escape, karakter escape harus direpresentasikan dengan urutan escape. Misalnya, gunakan
\\
untuk mewakili\
,\\t
untuk mewakili tab\t
, dan\\n
untuk mewakili baris baru. - Jika konstanta string diapit oleh tanda kutip tunggal, tanda kutip tunggal dalam konstanta tersebut harus direpresentasikan sebagai
\\'
sedangkan tanda kutip ganda dapat direpresentasikan sebagai"
atau\\"
. Contoh:'It\\'s milvus'
. - Jika konstanta string diapit oleh tanda kutip ganda, tanda kutip ganda di dalam konstanta harus direpresentasikan sebagai
\\"
sedangkan tanda kutip tunggal dapat direpresentasikan sebagai'
atau\\'
. Contoh:"He said \\"Hi\\""
.
- Karakter yang diapit oleh tanda kutip ganda atau tanda kutip tunggal di dalam ekspresi ditafsirkan sebagai konstanta string. Jika konstanta string menyertakan karakter escape, karakter escape harus direpresentasikan dengan urutan escape. Misalnya, gunakan