Open In Colab GitHub Repository

Filtrado de metadatos con LlamaIndex y Milvus

Este cuaderno ilustra el uso del almacén vectorial Milvus en LlamaIndex, centrándose en las capacidades de filtrado de metadatos. Aprenderá a indexar documentos con metadatos, a realizar búsquedas vectoriales con los filtros de metadatos incorporados de LlamaIndex y a aplicar las expresiones de filtrado nativas de Milvus al almacén vectorial.

Al final de este cuaderno, comprenderá cómo utilizar las funciones de filtrado de Milvus para limitar los resultados de la búsqueda basándose en los metadatos del documento.

Requisitos previos

Instalar dependencias

Antes de comenzar, asegúrese de tener instaladas las siguientes dependencias:

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

Si utilizas Google Colab, es posible que tengas que reiniciar el tiempo de ejecución (accede al menú "Tiempo de ejecución" situado en la parte superior de la interfaz y selecciona "Reiniciar sesión" en el menú desplegable).

Configurar cuentas

Este tutorial utiliza OpenAI para la incrustación de texto y la generación de respuestas. Es necesario preparar la clave API de OpenAI.

import openai

openai.api_key = "sk-"

Para utilizar el almacén vectorial Milvus, especifique su servidor Milvus URI (y opcionalmente con el TOKEN). Para iniciar un servidor Milvus, puede configurar un servidor Milvus siguiendo la guía de instalación de Milvus o simplemente probando Zilliz Cloud de forma gratuita.

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

Preparar los datos

Para este ejemplo, utilizaremos algunos libros con títulos similares o idénticos pero metadatos diferentes (autor, género y año de publicación) como datos de muestra. Esto ayudará a demostrar cómo Milvus puede filtrar y recuperar documentos basándose tanto en la similitud vectorial como en los atributos de metadatos.

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

Construir el índice

En esta sección, almacenaremos los datos de muestra en Milvus utilizando el modelo de incrustación por defecto (OpenAI's text-embedding-ada-002). Los títulos se convertirán en incrustaciones de texto y se almacenarán en un campo de incrustación densa, mientras que todos los metadatos se almacenarán en campos escalares.

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)

Filtros de metadatos

En esta sección, aplicaremos los filtros de metadatos y condiciones incorporados de LlamaIndex a la búsqueda Milvus.

Definir filtros de metadatos

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

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

Recuperar del almacén vectorial con filtros

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}

Múltiples filtros de metadatos

También puede combinar varios filtros de metadatos para crear consultas más complejas. LlamaIndex admite las condiciones AND y OR para combinar filtros. Esto permite una recuperación más precisa y flexible de los documentos en función de sus atributos de metadatos.

Condición AND

Pruebe un ejemplo de filtrado de libros publicados entre 1979 y 2010 (en concreto, donde 1979 < año ≤ 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}

Condición OR

Pruebe otro ejemplo que filtre libros escritos por 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}

Utilice los argumentos de palabras clave de Milvus

Además de las capacidades de filtrado incorporadas, puede utilizar las expresiones de filtrado nativas de Milvus mediante el argumento de palabra clave string_expr. Esto le permite pasar expresiones de filtrado específicas directamente a Milvus durante las operaciones de búsqueda, extendiéndose más allá del filtrado estándar de metadatos para acceder a las capacidades avanzadas de filtrado de Milvus.

Milvus proporciona opciones de filtrado potentes y flexibles que permiten una consulta precisa de sus datos vectoriales:

  • Operadores básicos: Operadores de comparación, filtros de rango, operadores aritméticos y operadores lógicos.
  • Plantillas de expresiones de filtrado: Patrones predefinidos para escenarios de filtrado comunes
  • Operadores especializados: Operadores específicos de tipos de datos para campos JSON o matrices

Para una documentación completa y ejemplos de expresiones de filtrado Milvus, consulte la documentación oficial de 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

¿Fue útil esta página?