Unit 03.03: Filtering before you rank
Metadata filters do two jobs at once: they enforce access control and they make retrieval better. The second is often overlooked, and it is substantial.
Constraints similarity cannot express
"Only refunds" and "only since 2025" are exact conditions. Similarity cannot express either - it has no way to represent a hard boundary, only degrees of topical closeness. Those constraints belong in a filter.
The table below ranks a small corpus by similarity alone, then applies the filters first and ranks what survives.
QUERY "refund"
RANKED BY SIMILARITY ALONE
c1 Refunds within 7 days. section: refunds 2026
c2 Refunds within 30 days. section: refunds 2023 <- stale
c3 Shipping takes 3 days. section: shipping 2026 <- wrong section
FILTERED FIRST (section = refunds, updated since 2025), THEN RANKED
c1 Refunds within 7 days. section: refunds 2026
Ranking alone kept a shipping document and a two-year-old policy. Both
occupied slots a current, on-section chunk could have used.
Ranking alone keeps c3, which is about shipping, and c2, which is two years stale. Both occupied top-k slots that a current, on-section chunk could have used.
The filter did not improve the embedding. It removed candidates that were competing for slots they had no business occupying - which is frequently a larger quality gain than switching embedding models, and costs a WHERE clause.
The mistake this prevents
The mistake is post-filtering: retrieve top-k, then drop the ineligible ones. You end up with fewer than k results, the dropped slots are wasted, and a restricted chunk was ranked - meaning it was read - before being removed. Filter first, always.
Takeaway
Apply metadata filters before ranking. It is the correct order for access control and it improves answer quality by keeping ineligible candidates out of the top-k competition entirely.
