Module 6: Designing Search Systems
4. Query Processing: From Query to Results
Overview
Query processing is the online phase: turning the user's query into relevant results. It covers embedding the query, kNN search, reranking, and latency optimization.
The query processing flow
User Query
↓
1. Query embedding (the OpenAI API)
↓
2. kNN search (the Vector DB)
↓
3. Metadata filtering (optional)
↓
4. Reranking (optional)
↓
5. Top-K results
Step 1: Query embedding
Input: The user's query (text)
Output: A 1536D vector (or 768D, 3072D depending on the model)
Example:
Query: "how to implement RAG with Pinecone"
→ The OpenAI API (text-embedding-3-small)
→ [0.23, -0.45, 0.12, ..., -0.34]
Latency: 50-200ms (the OpenAI API)
Step 2: kNN search
Input: The query embedding
Output: The top-K candidates (k=100 is typical)
A Pinecone example:
Query embedding: [0.23, -0.45, ...]
Index: "production-docs"
Top-K: 100
Filters: {"source": "rag-guide.pdf"}
→ Returns the 100 chunks with the highest cosine
Latency: 10-50ms (with HNSW)
Step 3: Metadata filtering
What is it?
Filtering the results by metadata BEFORE or AFTER the kNN.
Pre-filtering (before the kNN):
1. Filter by metadata: source = "rag-guide.pdf"
2. Run kNN only on that subset
Advantage: Faster (it searches a subset).
Disadvantage: If the filter is too restrictive, you get few results.
Post-filtering (after the kNN):
1. kNN returns the top-100
2. Filter the top-100 by metadata
Advantage: It guarantees K results.
Disadvantage: It can discard good candidates.
Step 4: Reranking
Why rerank?
The problem:
kNN returns the top-100 based on cosine
→ But cosine is the similarity of the embeddings
→ It does NOT consider the specific query-document interaction
The solution: A cross-encoder
Model: ms-marco-MiniLM (specialized in reranking)
For each (query, document) pair:
→ A relevance score [0-1]
→ Reorder the top-100 by this score
→ Return the final top-10
Example:
Query: "how to use Pinecone"
kNN top-3:
1. Doc A: "Pinecone is a vector database..." (cosine: 0.89)
2. Doc B: "A step-by-step guide to using Pinecone" (cosine: 0.87)
3. Doc C: "Pinecone vs Weaviate comparison" (cosine: 0.86)
Cross-encoder:
1. Doc B: Score 0.95 (most relevant: it's a usage guide)
2. Doc A: Score 0.75 (a general definition)
3. Doc C: Score 0.60 (a comparison, not direct usage)
Final ranking:
1. Doc B ✅
2. Doc A
3. Doc C
Latency: 100-300ms (the Cohere Rerank API)
Step 5: Returning the results
Typical output:
{
"query": "how to use Pinecone",
"results": [
{
"id": "chunk-456",
"score": 0.95,
"text": "A guide to using Pinecone...",
"metadata": {
"source": "rag-guide.pdf",
"page": 12
}
},
{
"id": "chunk-123",
"score": 0.75,
"text": "Pinecone is a vector database...",
"metadata": {
"source": "intro.pdf",
"page": 3
}
}
],
"latency_ms": 320
}
Trade-offs
kNN only (no reranking):
- ✅ Low latency (60-250ms)
- ❌ Limited precision
kNN + reranking:
- ✅ Better precision (reordered with a cross-encoder)
- ❌ Higher latency (160-550ms)
Decision: Use reranking if precision > speed (e.g. scientific search). Skip it if speed is critical (e.g. live chat).
Latency optimization
Technique 1: Cache the embeddings of frequent queries
Query: "what is RAG"
→ Check the cache
→ If it exists: use the cached embedding (latency: 0ms)
→ If NOT: generate the embedding (latency: 50-200ms)
Impact: 50-200ms saved on repeated queries.
Technique 2: Reduce top-K
Top-100 vs Top-50
→ A faster kNN (fewer candidates to evaluate)
→ A faster reranking (fewer cross-encoder evaluations)
Trade-off: Fewer candidates → lower recall.
Technique 3: Use selective reranking
If the query is simple (1-3 words):
→ kNN only
If the query is complex (a long question):
→ kNN + reranking
A complete example
Query: "the difference between HNSW and IVF"
Step 1: Embedding
The OpenAI API → [0.23, -0.45, ...]
Latency: 120ms
Step 2: kNN
Pinecone.query(
vector=[0.23, -0.45, ...],
top_k=100,
filter={"tags": "indexes"}
)
→ 100 candidates
Latency: 30ms
Step 3: Reranking
The Cohere Rerank API:
query="the difference between HNSW and IVF"
documents=[top-100]
→ The top-10 reordered
Latency: 200ms
Step 4: Return
The top-10 results
Total latency: 120 + 30 + 200 = 350ms
Summary
Key points:
- Query processing: Embedding → kNN → Reranking
- Typical latency: 160-550ms (with reranking)
- Reranking: A cross-encoder improves precision
- Optimization: Caching, reducing top-K, selective reranking
Next capsule: 05-ranking-strategies.md — Score fusion, RRF, MMR.