Pemfilteran Metadata dengan LlamaIndex dan Milvus
Buku catatan ini mengilustrasikan penggunaan penyimpanan vektor Milvus di LlamaIndex, dengan fokus pada kemampuan pemfilteran metadata. Anda akan mempelajari cara mengindeks dokumen dengan metadata, melakukan pencarian vektor dengan filter metadata bawaan LlamaIndex, dan menerapkan ekspresi pemfilteran asli Milvus ke penyimpanan vektor.
Pada akhir buku catatan ini, Anda akan memahami bagaimana memanfaatkan fitur penyaringan Milvus untuk mempersempit hasil pencarian berdasarkan metadata dokumen.
Prasyarat
Menginstal ketergantungan
Sebelum memulai, pastikan Anda telah menginstal dependensi berikut ini:
$ pip install llama-index-vector-stores-milvus llama-index
Jika Anda menggunakan Google Colab, Anda mungkin perlu memulai ulang runtime (Arahkan ke menu "Runtime" di bagian atas antarmuka, dan pilih "Restart session" dari menu tarik-turun).
Menyiapkan akun
Tutorial ini menggunakan OpenAI untuk penyematan teks dan pembuatan jawaban. Anda perlu menyiapkan kunci API OpenAI.
import openai
openai.api_key = "sk-"
Untuk menggunakan penyimpanan vektor Milvus, tentukan server Milvus Anda URI (dan secara opsional dengan TOKEN). Untuk memulai server Milvus, Anda dapat mengatur server Milvus dengan mengikuti panduan instalasi Milvus atau mencoba Zilliz Cloud secara gratis.
URI = "./milvus_filter_demo.db" # Use Milvus-Lite for demo purpose
# TOKEN = ""
Menyiapkan data
Untuk contoh ini, kita akan menggunakan beberapa buku dengan judul yang sama atau identik tetapi metadata (pengarang, genre, dan tahun terbit) yang berbeda sebagai data sampel. Ini akan membantu mendemonstrasikan bagaimana Milvus dapat memfilter dan mengambil dokumen berdasarkan kemiripan vektor dan atribut metadata.
from llama_index.core.schema import TextNode
nodes = [
TextNode(
text="Life: A User's Manual",
metadata={
"author": "Georges Perec",
"genre": "Postmodern Fiction",
"year": 1978,
},
),
TextNode(
text="Life and Fate",
metadata={
"author": "Vasily Grossman",
"genre": "Historical Fiction",
"year": 1980,
},
),
TextNode(
text="Life",
metadata={
"author": "Keith Richards",
"genre": "Memoir",
"year": 2010,
},
),
TextNode(
text="The Life",
metadata={
"author": "Malcolm Knox",
"genre": "Literary Fiction",
"year": 2011,
},
),
]
Membangun Indeks
Pada bagian ini, kita akan menyimpan data sampel di Milvus menggunakan model penyematan default (OpenAI's text-embedding-ada-002). Judul akan dikonversi menjadi sematan teks dan disimpan dalam bidang sematan padat, sementara semua metadata akan disimpan dalam bidang skalar.
from llama_index.vector_stores.milvus import MilvusVectorStore
from llama_index.core import StorageContext, VectorStoreIndex
vector_store = MilvusVectorStore(
uri=URI,
# token=TOKEN,
collection_name="test_filter_collection", # Change collection name here
dim=1536, # Vector dimension depends on the embedding model
overwrite=True, # Drop collection if exists
)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex(nodes, storage_context=storage_context)
2025-04-22 08:31:09,871 [DEBUG][_create_connection]: Created new connection using: 19675caa8f894772b3db175b65d0063a (async_milvus_client.py:547)
Penyaringan Metadata
Di bagian ini, kita akan menerapkan filter dan ketentuan metadata bawaan LlamaIndex untuk pencarian Milvus.
Tentukan filter metadata
from llama_index.core.vector_stores import (
MetadataFilter,
MetadataFilters,
FilterOperator,
)
filters = MetadataFilters(
filters=[
MetadataFilter(
key="year", value=2000, operator=FilterOperator.GT
) # year > 2000
]
)
Mengambil dari penyimpanan vektor dengan filter
retriever = index.as_retriever(filters=filters, similarity_top_k=5)
result_nodes = retriever.retrieve("Books about life")
for node in result_nodes:
print(node.text)
print(node.metadata)
print("\n")
The Life
{'author': 'Malcolm Knox', 'genre': 'Literary Fiction', 'year': 2011}
Life
{'author': 'Keith Richards', 'genre': 'Memoir', 'year': 2010}
Beberapa Filter Metdata
Anda juga dapat menggabungkan beberapa filter metadata untuk membuat kueri yang lebih kompleks. LlamaIndex mendukung kondisi AND dan OR untuk menggabungkan filter. Hal ini memungkinkan pengambilan dokumen yang lebih tepat dan fleksibel berdasarkan atribut metadata mereka.
Kondisi AND
Cobalah contoh pemfilteran untuk buku-buku yang diterbitkan antara tahun 1979 dan 2010 (khususnya, di mana 1979 < tahun ≤ 2010):
from llama_index.core.vector_stores import FilterCondition
filters = MetadataFilters(
filters=[
MetadataFilter(
key="year", value=1979, operator=FilterOperator.GT
), # year > 1979
MetadataFilter(
key="year", value=2010, operator=FilterOperator.LTE
), # year <= 2010
],
condition=FilterCondition.AND,
)
retriever = index.as_retriever(filters=filters, similarity_top_k=5)
result_nodes = retriever.retrieve("Books about life")
for node in result_nodes:
print(node.text)
print(node.metadata)
print("\n")
Life and Fate
{'author': 'Vasily Grossman', 'genre': 'Historical Fiction', 'year': 1980}
Life
{'author': 'Keith Richards', 'genre': 'Memoir', 'year': 2010}
Kondisi OR
Coba contoh lain yang memfilter buku-buku yang ditulis oleh Georges Perec atau Keith Richards:
filters = MetadataFilters(
filters=[
MetadataFilter(
key="author", value="Georges Perec", operator=FilterOperator.EQ
), # author is Georges Perec
MetadataFilter(
key="author", value="Keith Richards", operator=FilterOperator.EQ
), # author is Keith Richards
],
condition=FilterCondition.OR,
)
retriever = index.as_retriever(filters=filters, similarity_top_k=5)
result_nodes = retriever.retrieve("Books about life")
for node in result_nodes:
print(node.text)
print(node.metadata)
print("\n")
Life
{'author': 'Keith Richards', 'genre': 'Memoir', 'year': 2010}
Life: A User's Manual
{'author': 'Georges Perec', 'genre': 'Postmodern Fiction', 'year': 1978}
Gunakan Argumen Kata Kunci Milvus
Sebagai tambahan dari kemampuan pemfilteran bawaan, Anda dapat menggunakan ekspresi pemfilteran asli Milvus dengan argumen kata kunci string_expr. Hal ini memungkinkan Anda untuk memberikan ekspresi penyaringan tertentu secara langsung ke Milvus selama operasi pencarian, melampaui penyaringan metadata standar untuk mengakses kemampuan penyaringan lanjutan Milvus.
Milvus menyediakan opsi penyaringan yang kuat dan fleksibel yang memungkinkan kueri yang tepat untuk data vektor Anda:
- Operator Dasar: Operator perbandingan, filter rentang, operator aritmatika, dan operator logika
- Template Ekspresi Filter: Pola yang telah ditentukan sebelumnya untuk skenario pemfilteran yang umum
- Operator Khusus: Operator khusus tipe data untuk bidang JSON atau larik
Untuk dokumentasi lengkap dan contoh ekspresi pemfilteran Milvus, lihat dokumentasi resmi Pemfilteran Milvus.
retriever = index.as_retriever(
vector_store_kwargs={
"string_expr": "genre like '%Fiction'",
},
similarity_top_k=5,
)
result_nodes = retriever.retrieve("Books about life")
for node in result_nodes:
print(node.text)
print(node.metadata)
print("\n")
The Life
{'author': 'Malcolm Knox', 'genre': 'Literary Fiction', 'year': 2011}
Life and Fate
{'author': 'Vasily Grossman', 'genre': 'Historical Fiction', 'year': 1980}
Life: A User's Manual
{'author': 'Georges Perec', 'genre': 'Postmodern Fiction', 'year': 1978}