Open In Colab GitHub Repository

Фильтрация метаданных с помощью LlamaIndex и Milvus

Этот блокнот иллюстрирует использование векторного хранилища Milvus в LlamaIndex, уделяя особое внимание возможностям фильтрации метаданных. Вы узнаете, как индексировать документы с метаданными, выполнять векторный поиск с помощью встроенных в LlamaIndex фильтров метаданных и применять собственные выражения фильтрации Milvus к векторному хранилищу.

К концу этого блокнота вы поймете, как использовать функции фильтрации Milvus для сужения результатов поиска на основе метаданных документа.

Необходимые условия

Установка зависимостей

Прежде чем приступить к работе, убедитесь, что у вас установлены следующие зависимости:

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

Если вы используете Google Colab, вам может потребоваться перезапустить среду выполнения (перейдите в меню "Runtime" в верхней части интерфейса и выберите "Restart session" из выпадающего меню).

Настройка учетных записей

В этом учебнике используется OpenAI для встраивания текста и генерации ответов. Вам необходимо подготовить ключ API OpenAI.

import openai

openai.api_key = "sk-"

Чтобы использовать векторное хранилище Milvus, укажите свой сервер Milvus URI (и, по желанию, TOKEN). Чтобы запустить сервер 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,
        },
    ),
]

Построение индекса

В этом разделе мы сохраним образцы данных в Milvus, используя модель встраивания по умолчанию (OpenAI's text-embedding-ada-002). Заголовки будут преобразованы в текстовые вкрапления и сохранены в плотном поле вкраплений, а все метаданные будут сохранены в скалярных полях.

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

Попробуйте другой пример, который фильтрует книги, написанные либо Жоржем Переком, либо Китом Ричардсом:

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

В дополнение к встроенным возможностям фильтрации вы можете использовать собственные выражения фильтрации Milvus с помощью аргумента ключевого слова string_expr. Это позволяет передавать определенные выражения фильтрации непосредственно в Milvus во время поисковых операций, выходя за рамки стандартной фильтрации метаданных и получая доступ к расширенным возможностям фильтрации Milvus.

Milvus предоставляет мощные и гибкие возможности фильтрации, которые позволяют выполнять точные запросы к векторным данным:

  • Основные операторы: Операторы сравнения, фильтры диапазонов, арифметические операторы и логические операторы.
  • Шаблоны выражений фильтрации: Предопределенные шаблоны для распространенных сценариев фильтрации
  • Специализированные операторы: Операторы, специфичные для типов данных, для полей JSON или массивов.

Для получения полной документации и примеров использования выражений фильтрации Milvus обратитесь к официальной документации 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}

Попробуйте Managed Milvus бесплатно

Zilliz Cloud работает без проблем, поддерживается Milvus и в 10 раз быстрее.

Начать
Обратная связь

Была ли эта страница полезной?