The problem
Hard filtering loses good results. If a customer's spec calls for a 4-inch mounting and the closest available product has a 4.25-inch mounting, hard filters drop it from the response — even though it's the right answer for that buyer 90% of the time. The previous Product Finder did this constantly, and search OKR metrics showed the cost: customers gave up early or fell back to manual catalogs.
The rewrite replaces hard filters with a soft-filtering ranker that surfaces strong matches first, weaker matches behind them, and never silently throws away a candidate. Plus ML-driven image similarity for queries where text alone misses.
Architecture
Three Core Decisions
1. Soft filters, never hard drops
Filters declare preferences with weights, not gates. A 4-inch mounting requirement scores a 4-inch product highest, a 4.25-inch product slightly lower, and a 6-inch product lowest — but all three appear in the result set, ordered. The buyer keeps control instead of the index silently editing their query.
2. Weighted ranking by attribute meaning
Not all attribute matches are equal. Mounting size mismatches almost always matter, so it weighs 5×. Application (commercial / residential / industrial) matters often, so it weighs 2×. Other attributes weigh 1× each. The weights are tunable per category and were calibrated against existing customer-spec data, not guessed.
3. Match-strength buckets surfaced to the UI
Soft filtering only works if the buyer can see match quality. Each result is bucketed Strong / Medium / Weak based on how many of the high-weight attributes match. The PF card shows the bucket as a chip, so a Weak match never gets confused with a Strong one — even though both appear in the response.
Latency budgets — explicit and per-tier
A flat p90 budget breaks down once the manufacturer set a customer is searching against varies from 50 to 1000+. So the budgets are tiered against the size of the candidate set:
ML image similarity — vector search alongside text
Buyers often have a photo or datasheet snippet but don't know the exact text query. We added an image-similarity vector index on top of Elasticsearch / OpenSearch — the system encodes the query image, runs k-NN against the indexed catalog vectors, and merges the result set with the text-side soft-filtered results. Net effect: 21% improvement in search accuracy on the OKR test set.
Datasheet de-duplication
Products from different manufacturers often share the same underlying datasheet. Without de-duplication, the same logical product surfaces 3–4 times in a result set under different SKUs, hurting both relevance and the latency budget. The de-dup layer runs at index time, not query time — datasheet hashes are computed and consolidated cost / lead-time onto the canonical key, so the query path stays clean.
Stack
- Elasticsearch + OpenSearch — text index and vector index
- Python ranker, weight registry per category
- Datasheet hashing + consolidation pipeline at index time
- Internal latency dashboards covering DB / API / network breakdown at p50 / p90 / p95