Open In Colab GitHub Repository

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}

Coba Milvus yang Dikelola secara Gratis

Zilliz Cloud bebas masalah, didukung oleh Milvus dan 10x lebih cepat.

Mulai
Umpan balik

Apakah halaman ini bermanfaat?