Rank products 19% better than keyword search
SIE runs open-source search models behind one API. Add learned search terms to each product once, keep the search engine you already run, and shoppers find the products they meant even when their words differ from your listings.
OpenSearch doc-v3-gte on SIE
Top 3 are exact matchesryobi flashlight
- 1 Ryobi RFL905 160-Lumen … Cree LED Flashlight … Exact
- 2 Ryobi One+ P704 18V … Cordless Flashlight w/ Rotating Head … Exact
- 3 RYOBI P705 One+ 18V … LED 130 Lumen Flashlight … Exact
BM25, same search Replacement bulbs at ranks 1–3
Keyword search ranks the accessories above the product
BM25, Elasticsearch English analyzer
No scooter in the top 3pride mobility scooter
- 1 Pride Mobility Cup Holder Folding Go-Go Scooter C-Style Molded Seat Armrest Complement
- 2 Pride Mobility Scooter Rear Basket Center Support with Free Holding Clevis Pin Complement
- 3 Clip Cane Holder for Pride Mobility Scooters (Set of 2) Complement
BM25 favours short accessory listings that repeat the search words. Its first scooter labelled Exact is at rank 11; SIE ranks three scooters first.
- Baymard Institute 56% of online stores fail shoppers’ searches; 54% stumble on abbreviations like ‘tv’
Ecommerce Search UX 2026: 8 Search “Query Types” UX Best Practices. At Staples, “users get different results if they query for ‘television’ instead of ‘tv’.”
19% better product ranking than keyword search, on 8,956 Amazon searches
8,956 real Amazon shopping searches across 482,105 products, with human relevance labels
- Score
- nDCG@10: 0.395 against 0.330 for BM25
- Confirmed
- On 279 Wayfair searches: 0.739 against 0.704
- Prices
- List prices, 11 Oct 2026; searches run no model on SIE
Send the search and your listings, rank by shared terms
from sie_sdk import SIEClientclient = SIEClient(api_key="sk-sie-…")query = "querywayfair comforters"documents = [ "document 1···wayfair basics® comforter set···", "document 2···wayfair sleep medium weight all season polyester down alternative comforter···", "document 3···wayfair basics® reversible quilt set···", "document 4wayfair basics single curtain rod. Curtain Hardware & Accessories", "document 5wayfair basics peva shower curtain liner", "document 6wayfair basics round single curtain rod. Curtain Hardware & Accessories",]model = "modelopensearch-project/opensearch-neural-sparse-encoding-doc-v3-gte"q = client.encode(model, [{"text": query}], output_types=["sparse"], is_query=True)[0]["sparse"]docs = client.encode(model, [{"text": d} for d in documents], output_types=["sparse"], is_query=False)weights = {int(t): float(w) for t, w in zip(q["indices"], q["values"])}scores = [ sum(weights.get(int(t), 0.0) * float(w) for t, w in zip(d["sparse"]["indices"], d["sparse"]["values"])) for d in docs]for i in sorted(range(len(documents)), key=lambda i: -scores[i]): print(f"{scores[i]:.3f} {documents[i]}")import { SIEClient } from '@superlinked/sie-sdk';
const client = new SIEClient(undefined, { apiKey: 'sk-sie-…' });
const query = "wayfair comforters";
const documents = [
"···wayfair basics® comforter set···",
"···wayfair sleep medium weight all season polyester down alternative comforter···",
"···wayfair basics® reversible quilt set···",
"wayfair basics single curtain rod. Curtain Hardware & Accessories",
"wayfair basics peva shower curtain liner",
"wayfair basics round single curtain rod. Curtain Hardware & Accessories",
];
const model = 'opensearch-project/opensearch-neural-sparse-encoding-doc-v3-gte';
const [q] = await client.encode(model, [{ text: query }], {
outputTypes: ['sparse'],
isQuery: true,
});
const docs = await client.encode(
model,
documents.map((text) => ({ text })),
{ outputTypes: ['sparse'], isQuery: false },
);
const weights = new Map<number, number>();
q!.sparse!.indices.forEach((id, i) => weights.set(Number(id), Number(q!.sparse!.values[i])));
const ranked = documents
.map((doc, i) => {
const d = docs[i]!.sparse!;
let score = 0;
d.indices.forEach((id, j) => {
score += (weights.get(Number(id)) ?? 0) * Number(d.values[j]);
});
return { doc, score };
})
.sort((a, b) => b.score - a.score);
console.log(ranked);# Encode the query with is_query, then the listings; rank by sparse dot product.
curl https://api.superlinked.com/v1/encode/opensearch-project%2Fopensearch-neural-sparse-encoding-doc-v3-gte \
-H "Authorization: Bearer sk-sie-…" \
-H "Content-Type: application/json" \
-d "{\"items\":[{\"text\":\"wayfair comforters\"}],\"params\":{\"output_types\":[\"sparse\"],\"options\":{\"is_query\":true}}}" \
-H "Accept: application/json" -o query.json
curl https://api.superlinked.com/v1/encode/opensearch-project%2Fopensearch-neural-sparse-encoding-doc-v3-gte \
-H "Authorization: Bearer sk-sie-…" \
-H "Content-Type: application/json" \
-d "{\"items\":[{\"text\":\"···wayfair basics® comforter set···\"},{\"text\":\"···wayfair sleep medium weight all season polyester down alternative comforter···\"},{\"text\":\"···wayfair basics® reversible quilt set···\"},{\"text\":\"wayfair basics single curtain rod. Curtain Hardware & Accessories\"},{\"text\":\"wayfair basics peva shower curtain liner\"},{\"text\":\"wayfair basics round single curtain rod. Curtain Hardware & Accessories\"}],\"params\":{\"output_types\":[\"sparse\"],\"options\":{\"is_query\":false}}}" \
-H "Accept: application/json" -o listings.json
jq --slurpfile q query.json '($q[0].items[0].sparse | [.indices, .values] | transpose | map({key: (.[0] | tostring), value: .[1]}) | from_entries) as $w | [.items | to_entries[] | {listing: .key, score: ([.value.sparse.indices, .value.sparse.values] | transpose | map(($w[.[0] | tostring] // 0) * .[1]) | add // 0)}] | sort_by(-.score)' listings.jsonBuild the "Sparse embeddings" capability into my app using the Superlinked Inference Engine (SIE).
Context
- SIE is an OpenAI-style inference API. Python SDK: `from sie_sdk import SIEClient`; TypeScript: `@superlinked/sie-sdk`.
- Base URL: https://api.superlinked.com (or my regional endpoint). Auth: Bearer key from env `SIE_API_KEY` (never hard-code it).
- Model: opensearch-project/opensearch-neural-sparse-encoding-doc-v3-gte (SIE primitive: /encode). Keep the model id configurable.
Task
- Input: a search query plus the listings to rank.
- Behaviour: return the listings ranked by sparse dot product with the query, with a score per listing
- Send two POST /v1/encode requests: one item {text: query} with params {output_types: ["sparse"], options: {is_query: true}}, then all listings in one batch with params {output_types: ["sparse"], options: {is_query: false}}. Read items[i].sparse.indices (vocabulary ids) and .values (weights). Score each listing in caller code as the dot product of its sparse vector with the query vector over shared ids, and sort by descending score. In Python, use SIEClient.encode(..., output_types=["sparse"], is_query=True) for the query call and is_query=False for the listings; in TypeScript, pass isQuery: true and isQuery: false respectively. Do not issue one request per listing.
Deliverables
- A typed client wrapper, an application-level function for this task, error handling for timeouts/empty input, and unit tests with a stubbed client.
- Wire it into my existing stack (ask me which framework if unclear) and add a short usage example.way 3.49##fa 5.74##ir 6.48comfort 6.35##ers 4.19
- wayfair basics® comforter setExact 13.87
- wayfair sleep medium weight all season polyester down alternative comforterExact 13.28
- wayfair basics® reversible quilt setExact 12.47
- wayfair basics single curtain rodIrrelevant 6.22
- wayfair basics peva shower curtain linerIrrelevant 6.20
- wayfair basics round single curtain rodIrrelevant 6.14
Scores are the dot products of the recorded vectors; labels are Wayfair's.
Encode your catalog once; searches need no model call
Serverless API
We host the models; you call one API.
- No idle GPUs, pay for what you use
- SOC 2 Type 2, US or EU data residency
- $50 of credit to start, no card required
Self-hosted (Kubernetes)
SIE in your clusters, backed by our engineers.
- Data stays in your own cloud account
- Same models and API as Serverless
- Terraform to your cloud in minutes
Run locally
The open-source server on your own machine.
docker run --gpus all -p 8080:8080 ghcr.io/superlinked/sie-server:latest-cuda12-default