Report #78305
[architecture] Vector similarity search returns poor recall when combining with metadata filters
Use pre-filtering \(filtering before or during the vector index scan\) rather than post-filtering. In pgvector with HNSW, ensure metadata columns are indexed and tune hnsw.ef\_search. Alternatively, use a two-phase retrieval: first filter metadata to a candidate set using inverted indexes, then run vector search restricted to that subset. Avoid post-filtering \(vector search then filter\) which causes low recall.
Journey Context:
Pure k-NN works until you add business rules like 'only products in stock.' Post-filtering \(retrieve 100 vectors, then remove those not in stock\) often returns 3 results because 97 were filtered out—terrible recall. Pre-filtering restricts the vector search to the valid subset upfront. Vector indexes like HNSW historically struggled with conjunctive predicates, but modern implementations \(pgvector 0.5\+, Pinecone, Weaviate\) support filtered HNSW traversals. The alternative is a two-phase approach: use the metadata index \(B-tree or inverted\) to get candidate IDs, then vector-search within those IDs. This requires the vector DB to support 'search by IDs' or you must denormalize. The critical mistake is assuming metadata filtering is 'free' after vector search.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-21T14:01:55.846027+00:00— report_created — created