A shopper searches for “waterproof hiking shell.” BM25 finds products with those exact words. Vector search finds rain jackets whose descriptions never say “shell.” The business wants both, but also needs inventory filters, brand rules, price ranges, facets, and explainable relevance. That is the product-catalog hybrid search problem.

Short Version

Product catalog search is rarely dense-vector-only. It needs lexical search for exact terms, vector search for semantic recall, metadata filters for business constraints, and reranking for final relevance.

OpenSearch fits this workload when catalog search is already search-engine-shaped. The hard parts are score normalization, shard and mapping design, relevance debugging, and keeping the index synchronized with inventory and catalog systems.

Situation

Product catalogs contain mixed signals: exact identifiers (SKUs, model numbers, sizes, colors, brand names), natural language (titles, descriptions, reviews, support text), structured fields (price, category, inventory, tenant, region, eligibility), and business logic (margin, availability, promotions, compliance, personalization).

The Problem

Vector search improves semantic recall, but it does not replace exact matching or business filters. A semantic hit for an unavailable product is still a bad result. A perfect vector match from the wrong region may be a policy violation. Can the retrieval pipeline combine lexical precision, semantic recall, and hard business constraints without any one of them silently overriding the others?

How It Works

flowchart TD
    Query[shopper query] --> Lex[BM25 title and description]
    Query --> Vec[dense vector search]
    Lex --> Normalize[score normalization]
    Vec --> Normalize
    Normalize --> Filter[category inventory price filters]
    Filter --> Rerank[reranker and business rules]
    Rerank --> Results[product results and facets]
    Results --> Logs[query and click logs]
    Logs --> Eval[relevance evaluation]

The core pattern:

  1. Run a lexical query over title, brand, attributes, and description.
  2. Run a vector query over one or more embedding fields.
  3. Normalize or fuse scores.
  4. Apply hard filters for tenant, inventory, category, region, and compliance.
  5. Rerank a bounded candidate set.
  6. Log query, result IDs, filters, scores, clicks, and conversions.

OpenSearch’s normalization-processor search pipeline handles step 3: it runs between the query and fetch phases, applies a normalization technique (commonly min-max) to bring BM25 and k-NN scores onto a comparable scale, then combines them with a weighted technique such as arithmetic mean. This is a documented, general-availability feature — the pipeline definition is created once and attached to the index, not authored per query.

Architecture and Operating Model

Index shape. A catalog index should be intentionally denormalized. Each indexed product document should contain fields needed for search and filtering: title, normalized brand, category path, attributes, price bands, availability, tenant or marketplace, language, region, and embedding vectors.

Analyzer design. Product search needs analyzers for stemming, synonyms, punctuation, case normalization, and possibly language-specific behavior. Do not apply the same analyzer to SKU fields and prose fields.

Vector fields. A product can have separate embeddings for title, description, attributes, and reviews. Keep field purpose clear. If all text is collapsed into one embedding, debugging relevance gets harder.

Filters. Some filters are hard constraints: tenant, region, availability, compliance, deleted state. Others are user refinements: price, category, brand, rating. Hard constraints should never be left to reranking.

Reranking. Rerankers should operate on a bounded result set, not the whole index. They can incorporate semantic relevance, product quality, availability, and business rules. Keep the reranker deterministic enough to debug.

Evaluation. Maintain a query set: head queries, tail queries, exact SKU queries, vague semantic queries, misspellings, and zero-result queries. Review search changes against this set before deployment.

In Practice

A database engineer should view OpenSearch as a derived read model. The catalog database remains the source of truth for product state. The search index is rebuilt, refreshed, snapshotted, and monitored separately.

The most important operational boundary is ingestion. Product attributes, inventory updates, price changes, and embedding updates move at different speeds. The platform should make freshness explicit: product metadata may update in seconds, embeddings may update in minutes, and offline relevance features may update in batches.

Do not let the vector index hide stale inventory. Availability should be a structured filter tied to a reliable feed.

Where It Breaks

Failure modeSymptomFix
Score scales do not matchVector results dominate exact matches or disappearUse normalization and query-set evaluation
Filters applied too lateUnavailable or unauthorized products appearApply hard filters before final response
Shards too small or too manyCluster overhead and unstable latencyReview shard sizing and lifecycle policy
Embeddings staleProduct meaning changes but vector does notVersion embeddings and monitor lag
Reranker opaqueSearch team cannot explain result orderLog features, scores, and candidate stages

Security, Cost, Observability, and Failure Notes

Security is mainly field-level and tenant-level discipline. Do not index restricted products into a shared searchable surface without query-time enforcement. If products have market or contractual restrictions, those restrictions belong in filters.

Cost comes from denormalized document size, vector fields, replicas, shard count, query fanout, and reranking compute. Hybrid search can be more expensive than either BM25 or vector search alone because it runs both.

Observability should include indexing lag, query latency by stage, zero-result rate, no-click rate, filter selectivity, top slow queries, shard hot spots, refresh lag, and relevance metrics from the query set.

Failure modes include stale inventory, synonym regressions, analyzer mistakes, vector model upgrades without backfills, and business rules that bury relevant products without explanation.

Decision Checklist

  • Which fields require exact matching?
  • Which fields should be embedded?
  • Which filters are hard constraints?
  • How fresh must inventory be?
  • How are lexical and vector scores combined?
  • What query set protects relevance during changes?
  • How are shards sized and rolled over?
  • Can the index be rebuilt from source systems?
  • Are query logs sufficient for relevance debugging?
  • What is the rollback plan for a bad relevance release?

What to Do Next

Problem: Product catalog search treats hybrid retrieval as “run BM25 and vectors and combine them,” without accounting for score-scale mismatch or hard business constraints that must never be left to reranking.

Solution: Use OpenSearch’s normalization-processor pipeline to put BM25 and vector scores on a comparable scale, apply tenant/region/availability/compliance as hard filters before reranking, and rerank only a bounded candidate set.

Proof: The protected query set (including exact SKU lookups, discontinued-item lookups, and restricted-region lookups) passes after every relevance change, and zero-result rate is tracked separately from low-click rate.

Action: This week, confirm a normalization-processor pipeline is attached to the catalog index, and build the protected query set if it does not already exist.

Operating Guardrails

Treat every catalog relevance change as a release. Analyzer changes, synonym updates, vector model changes, boost changes, and reranker changes should run against the same protected query set before deployment. Include boring queries in that set: exact SKU lookup, discontinued item lookup, restricted-region lookup, and empty inventory lookup.

Keep the catalog index rebuildable. Product data, inventory state, pricing rules, and embeddings may come from different systems, but the index should have a deterministic replay path. If a bad mapping or vector model ships, the team should be able to create a replacement index, replay source data, compare relevance, and switch aliases without hand-editing production documents.

Watch zero-result queries separately from low-click queries. Zero results often indicate analyzer, filter, or inventory-feed problems. Low clicks usually indicate ranking or merchandising problems. Blending them into one “search quality” metric hides the fix path.

Sources to Verify