Metadata filtering
Metadata filtering limits a vector search to records whose labels, such as category or year, match rules you set.
A vector database is a store that finds records by meaning. Each record gets an embedding, a list of numbers that stands for its meaning. A search returns the records whose numbers are closest to the question. Metadata filtering adds plain rules on top. It uses small labels stored next to each record, for example a category or a year.
Why bother? Closeness in meaning cannot express everything. A shop might need results that are in stock, near the user or inside a price range. In Chroma, for example, you can pass a rule called where, such as page equals 10, and only records with that label are searched. The search then ranks only what passes.
When the filter runs matters. Post-filtering searches first and then throws out records that do not match. So you cannot know ahead of time how many results will be left. Pre-filtering finds the allowed records first, and the search only considers those.
For engineers: pgvector can use HNSW, an approximate index that trades a little accuracy for speed. By default its search looks at 40 candidates (the ef_search setting). If a filter matches 10% of rows, only about 4 of those 40 rows match on average, so you can get far fewer results than you asked for. pgvector 0.8.0 added iterative index scans, which keep scanning until enough results are found. Weaviate keeps an inverted index (a lookup from each label to the records that have it) next to its HNSW index. That lets it filter first without checking every record one by one.
Meaning-based search alone cannot follow hard rules.
Follow one search that must obey a rule.
- 1 · tagEach record is stored with its vector plus metadata, which are key-value pairs such as category or year.
- 2 · askThe query arrives with a filter expression, for example category equals digestive system.
- 3 · allowThe database uses an index of metadata values to list which records match the filter.
- 4 · searchThe vector search only adds records from that list to the results.
- 5 · returnIt stops once it has the number of results asked for.
The filter is a hard yes or no; similarity only ranks what passes.
| Who | What they ask | What it works with |
|---|---|---|
| Online shop | “Which products in stock match this description?” | Only products that are in stock |
| Health app | “What helps with disease prevention?” | Passages tagged with the digestive system category |
| Document search | “What does page 10 say?” | Only records whose page field is 10 |
- Results can be limited to records whose value is in a list you give.
- Rules can be combined with AND and OR.
- Pre-filtering picks the allowed records first, so the search is not left short the way post-filtering can be.
- A filter can only check fields that were stored as metadata.
- In pgvector with an approximate index, filtering happens after the index scan, so results can come back short.
- Filtering fast usually needs extra setup, such as an index on the filtered field.
Sources used
This explainer is written in original language. The links below support its factual claims.
- docsFilter by metadata, Pinecone · read 28 Sept 2026
- docsFiltering, Weaviate · read 28 Sept 2026
- docsFiltering, Qdrant · read 28 Sept 2026
- docsMetadata Filtering, Chroma · read 28 Sept 2026
- repopgvector README, pgvector · read 28 Sept 2026