Оптимизация Django ORM для гибридных запросов (PostgreSQL + Vector Similarity Search)
Я реализую систему RAG (Retrieval-Augmented Generation), в которой необходимо совместить традиционную для Django ORM фильтрацию с поиском векторного сходства. Конкретный рабочий процесс должен:
Сначала отфильтруйте товары по стандартным реляционным полям (например, category="books")
Затем выполните поиск векторного сходства только для этого отфильтрованного подмножества описаний товаров
Текущая реализация и проблемы:
# Current inefficient approach (two separate operations)
books = Product.objects.filter(category="books") # Initial DB query
vectors = get_embeddings([b.description for b in books]) # Expensive embedding generation
results = faiss_search(vectors, query_embedding) # Vector search
Основные проблемы такого подхода:
- Требуется загрузка всех отфильтрованных записей в память
- Делает два отдельных прохода по данным
- Не использует собственные возможности PostgreSQL при использовании pgvector
Что я пробовал:
- Сырой SQL с pgvector:
query = """
SELECT id FROM products
WHERE category = 'books'
ORDER BY description_embedding <=> %s
LIMIT 10
"""
results = Product.objects.raw(query, [query_embedding])
Проблема: Теряются такие преимущества Django ORM, как цепочка, методы модели.
- django-pgvector extension:
from pgvector.django import L2Distance
books = Product.objects.annotate(
distance=L2Distance('description_embedding', query_embedding)
).filter(category="books").order_by('distance')[:10]
Проблема: плохо масштабируется при сложных условиях фильтрации
Ожидаемое решение:
Ищем способ:
- Поддерживать выразительность Django ORM для первоначальной фильтрации.
- Эффективно комбинировать с векторным поиском по отфильтрованному подмножеству.
- Избегать загрузки всех записей в память.
- Желательно оставаться в рамках экосистемы Django.
Окружение:
- Django 5.0
- PostgreSQL 15 + pgvector
- Python 3.11