使用 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 支援AND 和OR 兩種條件來組合篩選條件。這可根據文件的元資料屬性,更精確、更靈活地檢索文件。
條件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}