Оптимизация 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

Что я пробовал:

  1. Сырой 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, как цепочка, методы модели.

  1. 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]

Проблема: плохо масштабируется при сложных условиях фильтрации

Ожидаемое решение:

Ищем способ:

  1. Поддерживать выразительность Django ORM для первоначальной фильтрации.
  2. Эффективно комбинировать с векторным поиском по отфильтрованному подмножеству.
  3. Избегать загрузки всех записей в память.
  4. Желательно оставаться в рамках экосистемы Django.

Окружение:

  • Django 5.0
  • PostgreSQL 15 + pgvector
  • Python 3.11
Вернуться на верх