Pencarian Tersaring dengan StructArray
Gunakan halaman ini untuk menambahkan penyaringan skalar ke pencarian vektor pada bidang StructArray. Penyaringan StructArray memiliki dua tingkatan: penyaring tingkat baris memilih entitas induk, sedangkan penyaring tingkat elemen membatasi elemen Struct mana yang ikut serta dalam pencarian vektor tingkat elemen.
Halaman ini menggunakan koleksi " tech_articles " dari "Create a StructArray Field". Koleksi tersebut memiliki bidang StructArray bernama " chunks", dengan subbidang skalar seperti " section", " page", " quality_score", dan " has_code", serta subbidang vektor untuk pencarian.
Pilih jenis filter
| Tujuan | Penggunaan | Perilaku hasil |
|---|---|---|
Saring berdasarkan bidang skalar tingkat atas, seperti category. | Ekspresi filter biasa. | Memilih entitas induk sebelum atau selama pencarian. |
| Membatasi pencarian vektor tingkat elemen ke elemen Struct yang sesuai dengan kondisi skalar. | element_filter. | Hanya mencari elemen Struct yang cocok dan dapat mengembalikan offset elemen yang cocok. |
| Memilih entitas berdasarkan apakah ada, semua, atau sejumlah tertentu elemen Struct yang sesuai dengan predikat. | MATCH_ANY, MATCH_ALL, MATCH_LEAST, MATCH_MOST, atau MATCH_EXACT. | Penyaringan tingkat baris. Operator-operator ini tidak mengembalikan offset secara langsung. |
Halaman ini menjelaskan cara menggunakan filter StructArray dalam alur kerja pencarian. Untuk aturan sintaks lengkap, jenis predikat yang didukung, dan matriks predikat yang tidak didukung, lihat Operator StructArray.
Penyaringan berdasarkan bidang tingkat atas
Gunakan ekspresi filter biasa jika kondisi tersebut berlaku untuk entitas induk, bukan untuk elemen Struct individu. Ini berfungsi baik dengan pencarian EmbeddingList maupun pencarian tingkat elemen.
from pymilvus import MilvusClient
from pymilvus.client.embedding_list import EmbeddingList
client = MilvusClient(
uri="http://localhost:19530",
token="root:Milvus",
)
query = EmbeddingList()
query.add([0.12, 0.21, 0.32, 0.44])
query.add([0.18, 0.23, 0.29, 0.36])
results = client.search(
collection_name="tech_articles",
data=[query],
anns_field="chunks[emb_list_vector]",
filter='category == "search"',
limit=3,
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
],
)
Filter di atas hanya memilih entitas yang bidang tingkat atasnya ( category ) adalah "search". Filter ini tidak mengidentifikasi satu elemen Struct yang cocok.
Penyaringan pencarian vektor tingkat elemen
Gunakan ` element_filter(structArrayField, predicate) ` ketika kondisi skalar harus diterapkan pada elemen Struct yang sama yang berpartisipasi dalam pencarian vektor tingkat elemen. Di dalam predikat, gunakan ` $[subfield] ` untuk merujuk pada subbidang skalar dari elemen Struct saat ini.
query_vector = [0.19, 0.24, 0.30, 0.37]
filter_expr = (
'category == "search" && '
'element_filter(chunks, '
'$[section] == "index" && '
'$[quality_score] > 0.9 && '
'$[has_code] == true)'
)
results = client.search(
collection_name="tech_articles",
data=[query_vector],
anns_field="chunks[emb]",
filter=filter_expr,
limit=5,
output_fields=[
"doc_id",
"title",
"chunks[text]",
"chunks[section]",
"chunks[page]",
"chunks[quality_score]",
"chunks[has_code]",
],
)
for hits in results:
for hit in hits:
print(
"doc_id:", hit["id"],
"distance:", hit["distance"],
"offset:", hit.get("offset"),
"entity:", hit["entity"],
)
Dalam contoh ini, predikat tingkat atas ` category == "search" ` memilih entitas kandidat, dan ` element_filter ` membatasi pencarian vektor tingkat elemen pada potongan di mana ` section`, ` quality_score`, dan ` has_code ` semuanya cocok dalam elemen Struct yang sama.
Peringatan
Saat Anda menggabungkan predikat tingkat atas dengan element_filter, letakkan element_filter di akhir ekspresi. Ekspresi filter hanya dapat berisi satu element_filter, dan Anda tidak dapat menyematkan element_filter atau MATCH_* di dalam operator StructArray lainnya.
Menyaring entitas dengan operator MATCH
Gunakan operator MATCH_* ketika filter harus menentukan apakah entitas induk memenuhi syarat berdasarkan elemen Struct-nya. Operator ini merupakan filter tingkat baris: mereka memilih entitas, tetapi tidak mengembalikan offset elemen secara langsung.
| Operator | Gunakan saat | Contoh |
|---|---|---|
MATCH_ANY | Setidaknya satu elemen Struct harus memenuhi predikat. | MATCH_ANY(chunks, $[section] == "index") |
MATCH_ALL | Semua elemen Struct harus memenuhi predikat. | MATCH_ALL(chunks, $[quality_score] > 0.5) |
MATCH_LEAST | Setidaknya N elemen Struct harus memenuhi predikat tersebut. | MATCH_LEAST(chunks, $[has_code] == true, threshold=2) |
MATCH_MOST | Paling banyak N elemen Struct harus memenuhi predikat tersebut. | MATCH_MOST(chunks, $[section] == "appendix", threshold=1) |
MATCH_EXACT | Tepat N elemen Struct harus memenuhi predikat. | MATCH_EXACT(chunks, $[section] == "summary", threshold=1) |
filter_expr = (
'category == "search" && '
'MATCH_ANY(chunks, $[section] == "index" && $[quality_score] > 0.9)'
)
results = client.search(
collection_name="tech_articles",
data=[query],
anns_field="chunks[emb_list_vector]",
filter=filter_expr,
limit=3,
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
"chunks[quality_score]",
],
)
Gunakan ` MATCH_ANY ` di sini karena hasil pencarian `EmbeddingList` berada pada tingkat entitas. Filter ini mensyaratkan setidaknya satu chunk dalam entitas tersebut merupakan chunk ` "index" ` dengan kualitas tinggi, namun hasil pencarian itu sendiri tetap mewakili entitas induk.
Gunakan filter dalam pencarian hibrida
Dalam pencarian hibrida, terapkan filter StructArray di mana kondisi tersebut harus berlaku. Filter tingkat atas dapat digunakan bersama oleh seluruh pencarian hibrida. element_filter harus dilampirkan ke permintaan tingkat elemen StructArray yang memerlukan batasan tingkat elemen.
from pymilvus import AnnSearchRequest, RRFRanker
query_vector = [0.19, 0.24, 0.30, 0.37]
title_req = AnnSearchRequest(
data=[query_vector],
anns_field="title_vector",
limit=10,
)
chunk_req = AnnSearchRequest(
data=[query_vector],
anns_field="chunks[emb]",
limit=10,
expr='element_filter(chunks, $[section] == "index" && $[quality_score] > 0.9)',
)
results = client.hybrid_search(
collection_name="tech_articles",
reqs=[title_req, chunk_req],
ranker=RRFRanker(),
filter='category == "search"',
limit=5,
output_fields=[
"doc_id",
"title",
"category",
"chunks[text]",
"chunks[section]",
"chunks[quality_score]",
],
)
Argumen ` filter ` menerapkan kondisi entitas tingkat atas, sedangkan ` expr ` pada ` chunk_req ` hanya membatasi permintaan vektor tingkat elemen StructArray. Untuk kombinasi pencarian hibrida yang didukung dan batasan versi tertentu, lihat Pencarian Hibrida dengan StructArray dan Batasan StructArray.
Ringkasan dukungan predikat
Gunakan subbidang skalar dalam predikat StructArray. Subbidang vektor bukanlah masukan predikat skalar.
| Jenis subbidang | Contoh predikat umum |
|---|---|
BOOL | $[has_code] == true, !($[has_code] == true) |
| Tipe bilangan bulat | $[page] >= 2, $[page] in [1, 2, 3] |
FLOAT, DOUBLE | $[quality_score] > 0.9, 0.7 < $[quality_score] < 0.95 |
VARCHAR | $[section] == "index", $[text] like "range%" |
| Subbidang vektor | Tidak didukung sebagai masukan predikat skalar $[...]. Gunakan subbidang vektor melalui pencarian vektor sebagai gantinya. |
Untuk kasus yang tidak didukung seperti jalur JSON, fungsi wadah array, fungsi pencocokan teks, predikat null pada $[...], fungsi Geometri, ekspresi Timestamptz, dan panggilan fungsi generik, lihat Operator StructArray.
Kesalahan umum
Menggunak
$[subfield]di luarelement_filteratauMATCH_*.Menggunakan
chunks.sectionalih-alih sintaks operator StructArray sepertielement_filter(chunks, $[section] == "index").Menggunakan
element_filtersaat Anda hanya memerlukan penyaringan tingkat baris. GunakanMATCH_ANYsebagai gantinya jika Anda hanya perlu memilih entitas.Mengharapkan `
MATCH_*` mengembalikan offset elemen. Operator-operator ini memilih entitas dan tidak mengidentifikasi satu elemen yang cocok secara otomatis.Menulis predikat boolean tanpa operator, seperti
$[has_code]. Gunakan perbandingan eksplisit seperti$[has_code] == true.Menempatkan `
element_filter` sebelum predikat tingkat atas dalam ekspresi filter yang sama.
Langkah selanjutnya
Untuk meninjau sintaks filter StructArray secara lengkap, baca StructArray Operators.
Untuk menjalankan pencarian vektor tanpa filter terlebih dahulu, baca Pencarian Vektor Dasar dengan StructArray.
Untuk membuat indeks skalar untuk filter StructArray yang sering digunakan, baca Indeks Bidang StructArray.
Untuk memeriksa batasan filter dan pencarian yang spesifik untuk versi tertentu, baca Batasan StructArray.