Skip to content
← All patterns

commerce

Catalogue Semantic Search

What’s like this, and in stock?

A vector index and a GSI on one table, answering different questions.

These are complements, not competitors. 'Something warm for winter camping' is a similarity question and only the vector index can answer it. 'Everything under fifty pounds, cheapest first' is a key condition, and the GSI answers it exactly, completely, in order, and for a fraction of the cost. Most features need both, and the tell is whether you could write the question down as a rule.

The model

Product

One product, searchable by meaning and queryable by price.

pk
CATEGORY#<category>
sk
PRODUCT#<productId>

Attributes: category (S), price (N), inStock (S), name (S), embedding (L)

Access patterns

  • SearchVectors · by-catalogueSomething like this, in stock

    A similarity question, narrowed to what you can actually sell.

  • Query · GSI1Everything in a price band

    A key condition, answered exactly and in order by the GSI.

Design notes

Top-K is a ceiling, not a page sizecost

TopK caps at 100 and there is no LastEvaluatedKey behind it. Filter a Query's results in your application and you can always go back for more rows; filter a search's results and you are spending from a fixed budget with no way to top it up. Anything expressible as a key condition belongs in one.

inStock is a string because the index requires itmodelling

A SearchSchema attribute must appear in AttributeDefinitions, and DynamoDB attribute definitions only accept S, N or B. A BOOL cannot be an inline filter, so the flag is stored as 'yes' and 'no'. This is the sort of constraint that only surfaces at CreateTable.

Exact where AWS is approximateoperations

The engine here compares against every entry and returns the true nearest. AWS builds an approximate index and trades a little recall for speed at scale. The API, the costs and the refusals are identical; the completeness guarantee is not, so do not use a vector index where you need full recall.

Taught in the course

product-vector-searchDynamoDB workbench
Ready to run
Explore an access patternSelect to load & run

A similarity question, narrowed to what you can actually sell.

Request
Execute against the local Dynoxide engine
ReturnedFiltered outChanged
PK(pk)
SK(sk)
category
embedding
inStock
name
price
CATEGORY#outdoor
PRODUCT#p-101S
outdoorS
[0.94, 0.08, 0.04, 0.02]L
yesS
Winter sleeping bagS
240N
CATEGORY#outdoor
PRODUCT#p-102S
outdoorS
[0.88, 0.15, 0.06, 0.03]L
yesS
Insulated sleeping matS
38N
CATEGORY#outdoor
PRODUCT#p-103S
outdoorS
[0.85, 0.19, 0.08, 0.04]L
noS
Thermal linerS
22N
CATEGORY#outdoor
PRODUCT#p-104S
outdoorS
[0.12, 0.92, 0.07, 0.03]L
yesS
Folding camp cupS
15N
CATEGORY#outdoor
PRODUCT#p-105S
outdoorS
[0.09, 0.14, 0.93, 0.05]L
yesS
Head torchS
46N
CATEGORY#cycling
PRODUCT#p-201S
cyclingS
[0.07, 0.10, 0.06, 0.95]L
yesS
Road helmetS
89N
Awaiting request
Your next query starts here.

Choose an access pattern above, or build your own request. See what comes back and what it costs.

Write transactions, streams, tags and TTL are among the operations this browser build leaves out. dynoxide's native build has them.