Búsqueda vectorial¶
Solo en PostgreSQL, sobre pgvector, y solo para las
columnas declaradas con vector_column().
Un método por columna¶
Cada vector_column() genera el suyo: find_similar_by_<columna>.
resultados = public_sync_api.post.find_similar_by_embedding(
text='cómo desplegar en producción', # se codifica con el encoder declarado
limit=10,
metric='cosine', # 'l2' | 'cosine' | 'inner_product'
threshold=0.5, # solo resultados por debajo de esa distancia
includes=['autor'],
)
for r in resultados:
print(r['distance'], r['record'].titulo)
Devuelve una lista de diccionarios con dos claves:
| Clave | Qué es |
|---|---|
record |
El DTO <Modelo>Read de la fila |
distance |
La distancia al vector de búsqueda — menor es más parecido |
Con un vector ya calculado¶
resultados = public_sync_api.post.find_similar_by_embedding(
vector=[0.12, -0.04, ...], # tantas dimensiones como declare la columna
limit=5,
)
text y vector son excluyentes: hay que pasar uno, y solo uno.
La métrica¶
Las funciones de pgvector devuelven distancia, no similitud:
| Métrica | Rango | Lectura |
|---|---|---|
cosine |
[0, 2] | 0 = idénticos, 1 = ortogonales, 2 = opuestos |
l2 |
[0, ∞) | Distancia euclídea. Depende de la magnitud de los vectores |
inner_product |
— | Producto interno negado: menor valor = más parecido |
Con metric='cosine', un threshold=0.5 deja pasar lo que se parezca en torno a un 75 % o más.
Combinar con filtros¶
El método acepta includes, rls y session. Si además necesitas filtrar por columnas, usa el
filtro de la columna vectorial en find_many, que ordena por distancia:
public_sync_api.post.find_many(
embedding='cómo desplegar en producción', # búsqueda por similitud
estado='publicado', # y filtro normal
limit=10,
)
Las columnas vectoriales no se cargan por defecto¶
Un vector de 768 dimensiones en cada fila de un listado es mucho tráfico para nada, así que se difieren:
posts = public_sync_api.post.find_many(limit=10) # sin embedding
posts = public_sync_api.post.find_many(limit=10, include_vectors=True) # con él
Al escribir¶
Si la columna declara source, el cliente codifica solo: escribes el texto y el vector se
calcula al guardar. Eso implica cargar el modelo de embeddings en el proceso que escribe, así
que la primera escritura de un proceso es más lenta.