Documentation Index Fetch the complete documentation index at: https://docs.joinrefine.io/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Filters narrow search and recommendation results based on product attributes. Use filters for price ranges, categories, availability, and custom metadata.
Basic Syntax
const results = await refine . search . text ({
query: 'summer dress' ,
topK: 24 ,
filters: [
{ field: 'price' , operator: 'lte' , value: 200 }
]
});
Each filter has three properties:
The product field to filter on. Use dot notation for nested metadata fields: metadata.color.
The comparison operator. See Operators below.
The value to compare against. Type depends on the operator.
Operators
Equality
eq (equals)
ne (not equals)
{ field : 'metadata.brand' , operator : 'eq' , value : 'Nike' }
Exact match. Case-sensitive for strings. { field : 'metadata.brand' , operator : 'ne' , value : 'Generic' }
Excludes exact matches.
Comparison
{ field : 'price' , operator : 'gt' , value : 50 }
Greater than (exclusive). { field : 'price' , operator : 'gte' , value : 50 }
Greater than or equal (inclusive). { field : 'price' , operator : 'lt' , value : 100 }
Less than (exclusive). { field : 'price' , operator : 'lte' , value : 100 }
Less than or equal (inclusive).
Array Operators
in (in array)
nin (not in array)
{ field : 'metadata.color' , operator : 'in' , value : [ 'red' , 'blue' , 'green' ] }
Field value is one of the provided values. { field : 'metadata.category' , operator : 'nin' , value : [ 'clearance' , 'discontinued' ] }
Field value is NOT one of the provided values.
Existence
{ field : 'metadata.salePrice' , operator : 'exists' , value : true }
Check if a field exists (true) or doesn’t exist (false).
Text Matching
{ field : 'title' , operator : 'match' , value : 'organic' }
Partial text match within the field. Case-insensitive.
Operator Reference
Operator Description Value Type Example eqEquals any { field: 'brand', operator: 'eq', value: 'Nike' }neNot equals any { field: 'status', operator: 'ne', value: 'discontinued' }gtGreater than number { field: 'price', operator: 'gt', value: 50 }gteGreater than or equal number { field: 'stock', operator: 'gte', value: 1 }ltLess than number { field: 'price', operator: 'lt', value: 100 }lteLess than or equal number { field: 'rating', operator: 'lte', value: 5 }inIn array array { field: 'size', operator: 'in', value: ['S', 'M', 'L'] }ninNot in array array { field: 'tag', operator: 'nin', value: ['test'] }existsField exists boolean { field: 'salePrice', operator: 'exists', value: true }matchText contains string { field: 'description', operator: 'match', value: 'cotton' }
Common Patterns
Price Range
filters : [
{ field: 'price' , operator: 'gte' , value: 50 },
{ field: 'price' , operator: 'lte' , value: 200 }
]
In Stock Only
filters : [
{ field: 'stock' , operator: 'gt' , value: 0 }
]
Multiple Categories
filters : [
{ field: 'metadata.category' , operator: 'in' , value: [ 'dresses' , 'skirts' , 'tops' ] }
]
Exclude Sale Items
filters : [
{ field: 'metadata.onSale' , operator: 'ne' , value: true }
]
Has Reviews
filters : [
{ field: 'metadata.reviewCount' , operator: 'gte' , value: 1 }
]
Brand Exclusion
filters : [
{ field: 'metadata.brand' , operator: 'nin' , value: [ 'Generic' , 'Unknown' ] }
]
Filter Logic
Multiple filters are combined with AND logic. All conditions must be true for a product to be included.
// Products where:
// - price is between $50-$200 AND
// - color is red, blue, or green AND
// - in stock
filters : [
{ field: 'price' , operator: 'gte' , value: 50 },
{ field: 'price' , operator: 'lte' , value: 200 },
{ field: 'metadata.color' , operator: 'in' , value: [ 'red' , 'blue' , 'green' ] },
{ field: 'stock' , operator: 'gt' , value: 0 }
]
OR logic isn’t directly supported. Use the in operator for “field equals A OR field equals B” scenarios.
Access nested metadata using dot notation:
// Product structure
{
productId : 'sku_001' ,
title : 'Summer Dress' ,
price : 79.99 ,
metadata : {
brand : 'Fashion Co' ,
color : 'red' ,
sizes : [ 'S' , 'M' , 'L' ],
details : {
material : 'cotton' ,
origin : 'Italy'
}
}
}
// Filter examples
{ field : 'metadata.brand' , operator : 'eq' , value : 'Fashion Co' }
{ field : 'metadata.color' , operator : 'in' , value : [ 'red' , 'blue' ] }
{ field : 'metadata.details.material' , operator : 'eq' , value : 'cotton' }
Sorting
Combine filters with sorting:
const results = await refine . search . text ({
query: 'shoes' ,
topK: 24 ,
filters: [
{ field: 'price' , operator: 'gte' , value: 50 },
{ field: 'stock' , operator: 'gt' , value: 0 }
],
sortBy: {
field: 'price' ,
order: 'ascending' // 'ascending' | 'descending'
}
});
Available sort fields depend on your catalog schema. Common options:
price
metadata.rating
metadata.popularity
metadata.createdAt
Sorting by relevance (default) uses the AI ranking. Sorting by other fields overrides the AI ranking.
Filter Options in Response
Search responses include available filter values:
const results = await refine . search . text ({ query: 'dress' , topK: 24 });
console . log ( results . filterOptions );
// [
// { field: 'metadata.color', values: ['red', 'blue', 'black', ...] },
// { field: 'metadata.size', values: ['XS', 'S', 'M', 'L', 'XL'] },
// { field: 'metadata.brand', values: ['Brand A', 'Brand B', ...] }
// ]
Use this to build dynamic filter UIs:
function buildFilterUI ( filterOptions : FilterOption []) {
return filterOptions . map ( option => `
<div class="filter-group">
<h4> ${ formatFieldName ( option . field ) } </h4>
${ option . values . map ( value => `
<label>
<input type="checkbox"
data-field=" ${ option . field } "
data-value=" ${ value } " />
${ value }
</label>
` ). join ( '' ) }
</div>
` ). join ( '' );
}
Filter on indexed fields for best performance
Use in with small arrays (under 100 values)
Avoid match on large text fields when possible
Combine price ranges into a single range filter
Next Steps
Text Search Search with text queries
Recommendations Filter recommendations too