Skip to main content

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:
field
string
required
The product field to filter on. Use dot notation for nested metadata fields: metadata.color.
operator
string
required
The comparison operator. See Operators below.
value
any
required
The value to compare against. Type depends on the operator.

Operators

Equality

{ field: 'metadata.brand', operator: 'eq', value: 'Nike' }
Exact match. Case-sensitive for strings.

Comparison

{ field: 'price', operator: 'gt', value: 50 }
Greater than (exclusive).

Array Operators

{ field: 'metadata.color', operator: 'in', value: ['red', 'blue', 'green'] }
Field value is 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

OperatorDescriptionValue TypeExample
eqEqualsany{ field: 'brand', operator: 'eq', value: 'Nike' }
neNot equalsany{ field: 'status', operator: 'ne', value: 'discontinued' }
gtGreater thannumber{ field: 'price', operator: 'gt', value: 50 }
gteGreater than or equalnumber{ field: 'stock', operator: 'gte', value: 1 }
ltLess thannumber{ field: 'price', operator: 'lt', value: 100 }
lteLess than or equalnumber{ field: 'rating', operator: 'lte', value: 5 }
inIn arrayarray{ field: 'size', operator: 'in', value: ['S', 'M', 'L'] }
ninNot in arrayarray{ field: 'tag', operator: 'nin', value: ['test'] }
existsField existsboolean{ field: 'salePrice', operator: 'exists', value: true }
matchText containsstring{ 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.

Metadata Fields

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('');
}

Performance Tips

  • 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