Smart filters
Beta
Let AI extract structured filters directly from the query. Instead of building filter UI, users describe what they want in natural language — Etoile figures out the filters.
1. Index with metadata
Smart filters work by scanning the metadata of your indexed documents. The richer the metadata, the more the AI can extract.
import { Etoile } from "@etoile-dev/client";
const etoile = new Etoile({
apiKey: process.env.ETOILE_API_KEY,
});
await etoile.index({
id: "product-1",
collection: "products",
title: "Ultraboost 22",
content: "Lightweight running shoe with responsive cushioning...",
metadata: {
category: "running",
brand: "Adidas",
price: 130,
rating: 4.6,
},
});const response = await fetch("https://etoile.dev/api/v1/index", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ETOILE_SECRET_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
id: "product-1",
collection: "products",
title: "Ultraboost 22",
content: "Lightweight running shoe with responsive cushioning...",
metadata: {
category: "running",
brand: "Adidas",
price: 130,
rating: 4.6,
},
}),
});curl -X POST "https://etoile.dev/api/v1/index" \
-H "Authorization: Bearer $ETOILE_SECRET_KEY" \
-H "Content-Type: application/json" \
-d '{
"id": "product-1",
"collection": "products",
"title": "Ultraboost 22",
"content": "Lightweight running shoe with responsive cushioning...",
"metadata": {
"category": "running",
"brand": "Adidas",
"price": 130,
"rating": 4.6
}
}'2. Search with autoFilters
Set autoFilters: true. The query is analyzed, filters are extracted, and a refined semantic query runs against them.
const { results, refinedQuery, appliedFilters } = await etoile.search({
query: "top-rated Adidas running shoes under $150",
collections: ["products"],
autoFilters: true,
});
// refinedQuery: "running shoes"
// appliedFilters: [
// { key: "brand", operator: "eq", value: "Adidas" },
// { key: "price", operator: "lte", value: 150 },
// { key: "rating", operator: "gte", value: 4.0 },
// ]const response = await fetch("https://etoile.dev/api/v1/search", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ETOILE_PUBLIC_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
query: "top-rated Adidas running shoes under $150",
collections: ["products"],
autoFilters: true,
}),
});
const { results, refinedQuery, appliedFilters } = await response.json();
// refinedQuery: "running shoes"
// appliedFilters: [
// { key: "brand", operator: "eq", value: "Adidas" },
// { key: "price", operator: "lte", value: 150 },
// { key: "rating", operator: "gte", value: 4.0 },
// ]curl -X POST "https://etoile.dev/api/v1/search" \
-H "Authorization: Bearer $ETOILE_PUBLIC_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "top-rated Adidas running shoes under $150",
"collections": ["products"],
"autoFilters": true
}'The response includes refinedQuery (the semantic core of the query, stripped of filterable attributes) and appliedFilters (the structured filters the AI extracted). Both are useful to display in your UI.
Restrict which keys are used
By default, Etoile scans all metadata fields to build the filter schema. Use autoFiltersKeys to restrict it to specific keys — useful when your metadata contains noisy fields like image URLs or internal IDs.
const { results, refinedQuery, appliedFilters } = await etoile.search({
query: "top-rated Adidas running shoes under $150",
collections: ["products"],
autoFilters: true,
autoFiltersKeys: ["brand", "category", "price", "rating"],
});const response = await fetch("https://etoile.dev/api/v1/search", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.ETOILE_PUBLIC_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
query: "top-rated Adidas running shoes under $150",
collections: ["products"],
autoFilters: true,
autoFiltersKeys: ["brand", "category", "price", "rating"],
}),
});curl -X POST "https://etoile.dev/api/v1/search" \
-H "Authorization: Bearer $ETOILE_PUBLIC_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "top-rated Adidas running shoes under $150",
"collections": ["products"],
"autoFilters": true,
"autoFiltersKeys": ["brand", "category", "price", "rating"]
}'How it works
- Discovery — a broad search scans up to 100 results to learn what metadata fields and values exist in your collection.
- Extraction — the AI maps the query onto those fields, producing structured filters and a refined query.
- Search — the refined query runs as a vector search with the extracted filters applied in the database.
Related
- Filter by metadata — pass your own filters explicitly
- Use metadata — attach fields at index time
- Search (POST) — API reference