mirror of
https://github.com/kbenestad/mdcms.git
synced 2026-06-18 15:24:32 +00:00
73 lines
1.9 KiB
Markdown
73 lines
1.9 KiB
Markdown
---
|
|
title: Hybrid Queries
|
|
sort: 120
|
|
section-id: query-language
|
|
keywords: hybrid queries, vector, relational, filters, combined, semantic search, metadata
|
|
description: Combining vector similarity and relational filters in NQL hybrid queries
|
|
language: en
|
|
---
|
|
|
|
# Hybrid Queries
|
|
|
|
Hybrid queries combine vector similarity search with relational filter predicates in a single SQL statement.
|
|
|
|
## Basic Hybrid Query
|
|
|
|
```sql
|
|
SELECT id, name, price, 1 - (embedding <=> $1) AS similarity
|
|
FROM products
|
|
WHERE category = 'electronics'
|
|
AND stock > 0
|
|
AND price < 500
|
|
ORDER BY embedding <=> $1
|
|
LIMIT 10;
|
|
```
|
|
|
|
## Query Planner Hints
|
|
|
|
```sql
|
|
-- Force pre-filter
|
|
SELECT /*+ PREFILTER */ id, name, 1 - (embedding <=> $1) AS score
|
|
FROM products WHERE category = 'electronics'
|
|
ORDER BY score DESC LIMIT 10;
|
|
|
|
-- Force post-filter
|
|
SELECT /*+ POSTFILTER */ id, name, 1 - (embedding <=> $1) AS score
|
|
FROM products WHERE price < 500
|
|
ORDER BY embedding <=> $1 LIMIT 10;
|
|
```
|
|
|
|
## Hybrid Full-Text + Vector (BM25)
|
|
|
|
```sql
|
|
WITH vector_search AS (
|
|
SELECT id, ROW_NUMBER() OVER (ORDER BY embedding <=> $1) AS rank
|
|
FROM documents ORDER BY embedding <=> $1 LIMIT 100
|
|
),
|
|
fts_search AS (
|
|
SELECT id, ROW_NUMBER() OVER (ORDER BY ts_rank_cd(tsv, query) DESC) AS rank
|
|
FROM documents, to_tsquery('english', $2) query
|
|
WHERE tsv @@ query ORDER BY ts_rank_cd(tsv, query) DESC LIMIT 100
|
|
),
|
|
rrf AS (
|
|
SELECT COALESCE(v.id, f.id) AS id,
|
|
(COALESCE(1.0/(60+v.rank),0) + COALESCE(1.0/(60+f.rank),0)) AS rrf_score
|
|
FROM vector_search v FULL OUTER JOIN fts_search f ON v.id = f.id
|
|
)
|
|
SELECT d.id, d.content, rrf.rrf_score
|
|
FROM rrf JOIN documents d ON d.id = rrf.id
|
|
ORDER BY rrf_score DESC LIMIT 10;
|
|
```
|
|
|
|
## Composite Scoring
|
|
|
|
```sql
|
|
SELECT id, name, price, rating,
|
|
(0.7 * (1 - (embedding <=> $1))
|
|
+ 0.2 * (rating / 5.0)
|
|
+ 0.1 * (1 - EXTRACT(DAYS FROM NOW() - created_at) / 365.0)
|
|
) AS composite_score
|
|
FROM products
|
|
WHERE available = true AND price < $2
|
|
ORDER BY composite_score DESC LIMIT 20;
|
|
```
|