Open In Colab GitHub Repository

使用 LlamaIndex 和 Milvus 進行元資料篩選

本筆記本說明如何在 LlamaIndex 中使用 Milvus 向量資料庫,重點在於元資料篩選功能。您將學習如何使用元資料索引文件、使用 LlamaIndex 的內建元資料篩選器執行向量搜尋,以及將 Milvus 的原生篩選表達式套用至向量儲存。

在本筆記簿結束時,您將瞭解如何利用 Milvus 的過濾功能,根據文件元資料縮小搜尋結果的範圍。

先決條件

安裝相依性

在開始之前,請確定您已安裝下列依賴項目:

$ pip install llama-index-vector-stores-milvus llama-index

如果您使用的是 Google Colab,您可能需要重新啟動運行時(導航到介面頂端的「運行」功能表,並從下拉式功能表中選擇「重新啟動會話」)。

設定帳號

本教程使用 OpenAI 進行文字嵌入和答案產生。您需要準備OpenAI API 密鑰

import openai

openai.api_key = "sk-"

若要使用 Milvus 向量存儲,請指定您的 Milvus 伺服器URI (可選擇使用TOKEN)。若要啟動 Milvus 伺服器,您可以依照Milvus 安裝指南設定 Milvus 伺服器,或直接免費試用Zilliz Cloud

URI = "./milvus_filter_demo.db"  # Use Milvus-Lite for demo purpose
# TOKEN = ""

準備資料

在這個範例中,我們會使用一些書名相似或相同,但元資料(作者、流派和出版年份)不同的書籍作為樣本資料。這將有助於展示 Milvus 如何根據向量相似性和元資料屬性來過濾和擷取文件。

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,
        },
    ),
]

建立索引

在本節中,我們將使用預設的嵌入模型 (OpenAI'stext-embedding-ada-002) 在 Milvus 中儲存範例資料。標題會轉換成文字嵌入,並儲存在密集嵌入欄位中,而所有的元資料則會儲存在標量欄位中。

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)

元資料篩選器

在本節中,我們將應用 LlamaIndex 內建的元資料篩選器和條件到 Milvus 搜尋。

定義元資料篩選器

from llama_index.core.vector_stores import (
    MetadataFilter,
    MetadataFilters,
    FilterOperator,
)

filters = MetadataFilters(
    filters=[
        MetadataFilter(
            key="year", value=2000, operator=FilterOperator.GT
        )  # year > 2000
    ]
)

使用篩選器從向量儲存中擷取

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}

多重元資料篩選器

您也可以結合多重元資料篩選器來建立更複雜的查詢。LlamaIndex 支援ANDOR 兩種條件來組合篩選條件。這可根據文件的元資料屬性,更精確、更靈活地檢索文件。

條件AND

試舉例篩選 1979 年至 2010 年間出版的書籍 (具體來說,1979 < 年份 ≤ 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}

條件OR

嘗試另一個過濾 Georges Perec 或 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}

使用 Milvus 的關鍵字論證

除了內建的篩選功能外,您也可以使用string_expr 關鍵字參數來使用 Milvus 原生的篩選表達式。這允許您在搜尋作業中直接傳送特定的篩選表達式給 Milvus,從而擴展到標準的元資料篩選之外,以存取 Milvus 的進階篩選功能。

Milvus 提供強大而靈活的篩選選項,可讓您精確地查詢向量資料:

  • 基本運算符號:比較運算符、範圍篩選、算術運算符和邏輯運算符
  • 篩選表達範本:常見篩選情況的預定義模式
  • 專用運算符:針對 JSON 或陣列欄位的特定資料類型運算符號

有關 Milvus 過濾表達式的全面說明文件和範例,請參閱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}

免費嘗試托管的 Milvus

Zilliz Cloud 無縫接入,由 Milvus 提供動力,速度提升 10 倍。

開始使用
反饋

這個頁面有幫助嗎?