← Ai Search / ai-search / configuration / retrieval
Filtering
Metadata filtering narrows down search results based on metadata, so only relevant content is retrieved. The filter is applied before retrieval, so you only query the documents that matter.
Filtering uses the metadata attributes extracted during indexing. To define custom attributes or use the built-in metadata attributes, refer to Metadata attributes.
AI Search can store string values longer than the filterable prefix. Filters only match the first 64 UTF-8 bytes of each indexed string. Vectorize can store string arrays, but does not currently index or filter them.
Here is an example of metadata filtering using the Workers binding:
const instance = env.AI_SEARCH.get("my-instance");
const results = await instance.search({
messages: [{ role: "user", content: "What is Cloudflare?" }],
ai_search_options: {
retrieval: {
filters: {
folder: "docs/getting-started/",
timestamp: { $gte: 1735689600 },
},
},
},
});Filter syntax
Filters are JSON objects where keys are metadata attribute names and values specify the filter condition.
Supported operators
| Operator | Description |
|---|---|
$eq |
Equals |
$ne |
Not equals |
$in |
Matches a stored scalar against any candidate scalar value |
$nin |
Excludes a stored scalar matching any candidate scalar value |
$lt |
Less than |
$lte |
Less than or equal to |
$gt |
Greater than |
$gte |
Greater than or equal to |
Implicit $eq
When you provide a direct value without an operator, it is treated as an equality check:
{
"ai_search_options": {
"retrieval": {
"filters": { "folder": "docs/getting-started/" }
}
}
}This is equivalent to:
{
"ai_search_options": {
"retrieval": {
"filters": { "folder": { "$eq": "docs/getting-started/" } }
}
}
}Range queries
Combine upper and lower bound operators to filter by ranges:
{
"ai_search_options": {
"retrieval": {
"filters": { "timestamp": { "$gte": 1735689600, "$lt": 1735900000 } }
}
}
}Multiple conditions (implicit AND)
When you specify multiple keys, all conditions must match:
{
"ai_search_options": {
"retrieval": {
"filters": {
"folder": "docs/getting-started/",
"timestamp": { "$gte": 1735689600 }
}
}
}
}$in operator
Match a stored scalar field against any value in the candidate array. $in does not search inside stored arrays:
{
"ai_search_options": {
"retrieval": {
"filters": { "folder": { "$in": ["docs/guides/", "docs/tutorials/"] } }
}
}
}"Starts with" filter for folders
Use range queries to filter for all files within a folder and its subfolders.
For example, consider this file structure:
- docs
- guide.pdf
- tutorials
- getting-started
- intro.pdf
- getting-started
Using { "folder": "docs/" } only matches files directly in that folder (like guide.pdf), not files in subfolders.
To match all files starting with docs/, use a range query:
{
"ai_search_options": {
"retrieval": {
"filters": { "folder": { "$gte": "docs/", "$lt": "docs0" } }
}
}
}This works because:
$gteincludes all paths starting withdocs/$ltwithdocs0excludes paths that do not start withdocs/(since0comes after/in ASCII)