Open In Colab GitHub Repository

Filtraggio dei metadati con LlamaIndex e Milvus

Questo quaderno illustra l'uso dell'archivio vettoriale Milvus in LlamaIndex, concentrandosi sulle capacità di filtraggio dei metadati. Imparerete a indicizzare i documenti con metadati, a eseguire ricerche vettoriali con i filtri di metadati integrati in LlamaIndex e ad applicare le espressioni di filtraggio native di Milvus all'archivio vettoriale.

Alla fine di questo quaderno, capirete come utilizzare le funzioni di filtraggio di Milvus per restringere i risultati delle ricerche in base ai metadati dei documenti.

Prerequisiti

Installare le dipendenze

Prima di iniziare, assicuratevi di aver installato le seguenti dipendenze:

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

Se si utilizza Google Colab, potrebbe essere necessario riavviare il runtime (andare al menu "Runtime" nella parte superiore dell'interfaccia e selezionare "Riavvia sessione" dal menu a discesa).

Impostazione degli account

Questa esercitazione utilizza OpenAI per l'incorporazione del testo e la generazione delle risposte. È necessario preparare la chiave API di OpenAI.

import openai

openai.api_key = "sk-"

Per utilizzare l'archivio vettoriale Milvus, specificare il server Milvus URI (e facoltativamente TOKEN). Per avviare un server Milvus, è possibile configurarlo seguendo la guida all'installazione di Milvus o semplicemente provando gratuitamente Zilliz Cloud.

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

Preparare i dati

Per questo esempio, utilizzeremo alcuni libri con titoli simili o identici ma con metadati diversi (autore, genere e anno di pubblicazione) come dati campione. In questo modo dimostreremo come Milvus possa filtrare e recuperare i documenti in base alla somiglianza vettoriale e agli attributi dei metadati.

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

Costruire l'indice

In questa sezione, memorizzeremo i dati di esempio in Milvus utilizzando il modello di incorporamento predefinito ( text-embedding-ada-002 di OpenAI). I titoli saranno convertiti in embedding di testo e memorizzati in un campo di embedding denso, mentre tutti i metadati saranno memorizzati in campi scalari.

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)

Filtri dei metadati

In questa sezione, applicheremo i filtri di metadati e le condizioni di LlamaIndex alla ricerca di Milvus.

Definire i filtri dei metadati

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

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

Recupero dall'archivio vettoriale con i filtri

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}

Filtri multipli per i metadati

È anche possibile combinare più filtri di metadati per creare query più complesse. LlamaIndex supporta sia le condizioni AND che OR per combinare i filtri. Ciò consente di recuperare in modo più preciso e flessibile i documenti in base ai loro attributi di metadati.

Condizione AND

Proviamo a fare un esempio di filtro per i libri pubblicati tra il 1979 e il 2010 (in particolare, dove 1979 < anno ≤ 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}

Condizione OR

Provate un altro esempio che filtra i libri scritti da Georges Perec o 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}

Utilizzare gli argomenti delle parole chiave di Milvus

Oltre alle funzionalità di filtraggio integrate, è possibile utilizzare le espressioni di filtraggio native di Milvus con l'argomento parola chiave string_expr. Ciò consente di passare espressioni di filtro specifiche direttamente a Milvus durante le operazioni di ricerca, andando oltre il filtraggio standard dei metadati per accedere alle capacità di filtraggio avanzate di Milvus.

Milvus offre opzioni di filtraggio potenti e flessibili che consentono di interrogare con precisione i dati vettoriali:

  • Operatori di base: Operatori di confronto, filtri di intervallo, operatori aritmetici e operatori logici.
  • Modelli di espressione di filtro: Modelli predefiniti per gli scenari di filtraggio più comuni.
  • Operatori specializzati: Operatori specifici per tipo di dati per campi JSON o array

Per una documentazione completa ed esempi di espressioni di filtraggio Milvus, consultare la documentazione ufficiale di Milvus Filtering.

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}

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started
Feedback

Questa pagina è stata utile?