Overview
Product search requires three things: relevance (full-text), filtering (facets), and performance (shard sizing). This mapping addresses all three.
Index settings + mapping (PUT /products-000001)
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1,
"analysis": {
"filter": {
"english_stemmer": { "type": "stemmer", "language": "english" },
"product_synonyms": {
"type": "synonym_graph",
"synonyms": [
"tv, television, telly",
"laptop, notebook, macbook => laptop"
]
}
},
"analyzer": {
"product_analyzer": {
"type": "custom",
"tokenizer": "standard",
"filter": ["lowercase", "product_synonyms", "english_stemmer"]
}
}
},
"index.max_result_window": 50000
},
"mappings": {
"dynamic": "strict",
"properties": {
"id": { "type": "keyword" },
"sku": { "type": "keyword" },
"name": {
"type": "text",
"analyzer": "product_analyzer",
"fields": {
"keyword": { "type": "keyword", "ignore_above": 256 },
"suggest": { "type": "completion" }
}
},
"description": { "type": "text", "analyzer": "product_analyzer" },
"brand": { "type": "keyword" },
"category": { "type": "keyword" },
"tags": { "type": "keyword" },
"price": { "type": "scaled_float", "scaling_factor": 100 },
"sale_price": { "type": "scaled_float", "scaling_factor": 100 },
"in_stock": { "type": "boolean" },
"stock_qty": { "type": "integer" },
"rating_avg": { "type": "half_float" },
"rating_count":{ "type": "integer" },
"images": { "type": "keyword", "index": false },
"attributes": { "type": "flattened" },
"created_at": { "type": "date" },
"updated_at": { "type": "date" }
}
}
}
Example search query (BM25 + filters + boost)
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "wireless headphones",
"fields": ["name^3", "description", "tags^2"],
"type": "best_fields",
"fuzziness": "AUTO"
}
}
],
"filter": [
{ "term": { "in_stock": true } },
{ "range": { "price": { "lte": 200 } } },
{ "terms": { "category": ["electronics", "audio"] } }
],
"should": [
{ "range": { "rating_avg": { "gte": 4, "boost": 1.5 } } }
]
}
},
"sort": [
{ "_score": "desc" },
{ "rating_count": "desc" }
],
"aggs": {
"brands": { "terms": { "field": "brand", "size": 20 } },
"price_range":{ "range": { "field": "price", "ranges": [
{ "to": 50 }, { "from": 50, "to": 200 }, { "from": 200 }
]}}
}
}