Semantic Search for Grocery: Substitutions, Pack Sizes, and Dietary Filters
Grocery search has its own shape
A grocery catalogue behaves differently from general retail, and semantic search for grocery has to account for four things that don't show up the same way elsewhere.
1. Substitution intent is constant
Shoppers ask for a category of alternatives, not one exact product: "something like oat milk," "a swap for eggs in baking," "what can I use instead of buttermilk." Semantic retrieval is genuinely good at this — it returns the cluster of alternatives, which is usually what the shopper wants, and it's especially useful when the exact item is out of stock.
2. Pack size and unit ambiguity
"Milk" could mean a pint or a six-litre catering pack. "Pasta" could be a 500g bag or a case. The query often needs disambiguating, and the results need clear unit pricing so the shopper can compare a 250g jar to a 1kg one.
3. Dietary and allergen filtering is high-stakes
"Gluten free pasta," "nut free snacks for a lunchbox," "dairy free chocolate." A wrong result here isn't just irrelevant — it's a safety issue. These belong in hard filters on structured attributes, not left to semantic similarity. The model can help find candidates; the allergen constraint has to be enforced, not ranked.
4. High volume, low margin
Grocery search runs a lot of queries against thin margins, so the per-query cost of an embedding call plus a re-ranking call matters more than in higher-margin retail. A small embedding model and a tight top-N are the defaults here.
Where semantic search helps
Natural-language and recipe-style queries ("ingredients for a roast dinner"), brand-to-generic and back, and substitution suggestions when stock runs out. On our semantic search project the multi-category, multi-supplier catalogue is the same shape a grocer runs — the difference is weighting the pipeline toward substitutions and keeping dietary constraints as hard filters.
The freshness angle
Grocery stock changes fast and varies by store, so the index has to reflect per-store availability. The price-and-stock fast path from the re-index design matters more here, not less — ranking an out-of-stock item is worse when the shopper needs it for dinner tonight.
Per-store stock, concretely
Grocery availability is store-specific and moves through the day. The search index needs a per-store stock signal, so "in stock at my store" is a hard filter rather than a hope, and an item that's out at one store but in at another ranks accordingly. When the exact item is unavailable, that same signal is what lets the search offer a substitution instead of just dropping the product from the results.
The substitution experience
When the shopper's item is out, don't return a bare "no results." Surface two or three semantic alternatives, each labelled with why it's a match: "also dairy-free," "same brand, larger pack," "same aisle, similar price." A grocery shopper mid-list wants a swap they can trust in two seconds, not a page they have to evaluate.
The margin math
Grocery runs enormous query volume against thin margins, so the per-query cost of an embedding call plus a re-ranking call is a real line item, not a rounding error. Three things keep it in check: a small embedding model, a tight top-N into the re-ranker, and caching the query embeddings and results for the head of the distribution — a large share of grocery searches are the same few hundred terms, and serving those from cache cuts the bill and the latency at once.
Where this stops being right
- Dietary filtering handled by semantic similarity instead of hard attributes is a liability — invest in the structured data first.
- A small, stable grocery range may not need semantic search at all.
- Per-query cost at grocery volume can be significant — a small embedding model and a tight candidate set aren't optional here.
FAQ
Should "gluten free" be a semantic match or a filter? A hard filter on a structured attribute. Allergen and dietary constraints are too high-stakes for soft ranking.
How does it handle "something like X"? Semantic retrieval returns the category of alternatives, which is often exactly what a grocery shopper wants.
Does per-store stock matter? Yes — grocery availability varies by store and changes fast, so the index needs a per-store stock signal on a fast update path.
ISTRALLEN builds grocery search weighted for substitutions with dietary constraints enforced as hard filters; see AI for Retail.