Back to Showcases
Retail & E-commerceStandard

E-commerce Product Recommendations

5,000 products, typed BOUGHT_WITH edges, price-filtered in one call

What if 'also bought' edges and semantic search lived in one engine, with the price filter in the same call?

Typed Behavioral EdgesHybrid QueryCross-Category Co-PurchaseFilter-Then-SearchBulk Edge ImportEdge Provenance

Zentara Pro Waterproof Outdoor Speaker

$380.42, Electronics. A Bluetooth speaker with outdoor, portable, waterproof positioning.

Its top 'also bought' result is a Midi Wrap Dress, surfaced by a real BOUGHT_WITH edge (customers bought them together), then ranked by description relevance. The co-purchase edges span all 8 categories.

5,000
Products
8
Categories
0.6ms
Also Bought
500 products
Network (3 hops)
01

Customers Also Bought

We asked SwarnDB: what was genuinely bought with this speaker? A hybrid query seeded by description, walked the BOUGHT_WITH edges, and ranked by relevance, returning 20 products in 0.6ms. The top result is a dress, surfaced because customers actually bought them together, then ranked by description relevance. Only 2 of 20 are electronics; the rest span 7 categories.

Key insight:The top 'also bought' is a dress, by real co-purchase, not a word overlap. Auditable back to the orders.

0.6msAlso Bought
#ProductCategoryEdge
1Vossmark Signature Midi Wrap DressClothingBOUGHT_WITH
2-5Various cross-category productsMixedBOUGHT_WITH
02

Cross-Category Co-Purchase

From one electronics product, the BOUGHT_WITH edges reach all 8 categories, because customers genuinely cross-shop and the order history records it. Clothing leads. This is not a word overlap; it is recorded behavior, with provenance behind every edge.

Key insight:Co-purchase edges from one product span all 8 categories. Clothing leads, by behavior, not by description.

all 8Categories Reached
CategoryEdgesWhy
Clothing19Frequently bought together
Electronics17Same domain, co-purchased
Sports & Outdoors3Outdoor activity bundles
Home & Kitchen3Everyday-use bundles
Food & Gourmet3Adventure lifestyle baskets
Beauty & Personal Care2Premium lifestyle baskets
Toys & Games2Entertainment bundles
Books1Adventure interest overlap
03

Co-Purchase Network Expansion

From one speaker, we walked the BOUGHT_WITH edges outward. One product. Three hops. 500 products across all 8 categories. The co-purchase graph is richly interconnected because real baskets cross categories.

Key insight:From ONE product, 3 hops over BOUGHT_WITH edges reach the catalog across all 8 categories.

500Products (3 hops)
DepthProductsCategoriesTime
1 hop50all 80.8ms
2 hops354all 81.1ms
3 hops500all 82.3ms
04

Bulk Edge Import

Co-purchase and co-view edges are derived from order and session logs, then bulk-imported as CSV or JSONL in one call. Every edge knows its type, confidence, and source events. No standing ETL job to keep a separate co-purchase graph aligned with the catalog.

Key insight:Millions of authored co-purchase edges, bulk-imported with provenance. No second store to sync.

CSV / JSONLBulk Import
Edge TypeDerived FromCarries
BOUGHT_WITHorder historyco-purchase count, provenance
VIEWED_WITHsession logsco-view count, provenance
05

Price-Filtered Recommendations

Filter-then-search fixes the in-budget set first ($20-$50), then ranks within it, returning the true top-k among qualified products. Combined with the co-purchase traversal, one call does the whole job. Traditional stacks need a search service, a price filter service, and application stitching. SwarnDB does it in 7.4ms.

Key insight:Filter-then-search returns the true top-k among in-budget products. One call, one round trip, 7.4ms.

7.4msFiltered Recs
06

Meet the Yoga Mat

Different product, different category. The Trailmark Summit Travel Yoga Mat ($22.49, Sports). One composable query: seed by description, traverse BOUGHT_WITH, rank by relevance. Result: 200 products across all 8 categories in 2.7ms, every one auditable to the orders behind its edge.

Key insight:From a $22 yoga mat, one hybrid query built a complete 'You Might Also Like' feed across all 8 categories.

2.7msFull Query
07

Search + Graph: One Query

The hybrid query returns 10 results that were both genuinely co-purchased with the seed and rank well by description, in 1.7ms. Plain vector search returns look-alikes with no behavioral signal. The graph traversal adds the 'also bought' structure, ranked by meaning, in one query.

1.7msHybrid Query

What Would This Take Without SwarnDB?

A side-by-side look at the traditional approach versus SwarnDB.

CapabilityTraditional StackSwarnDB
StoragePostgres + ML store + graph storeOne database, one object per product
'Also bought'Opaque ML outputTyped BOUGHT_WITH edges, with provenance
Cross-categoryManual merchandising rulesReal co-purchase edges
Price-filtered recsSearch + filter services + stitchingFilter-then-search, one call
Edge ingestStanding ETL sync jobBulk import CSV / JSONL
Search + relationshipsMultiple queries, app-level joinsOne hybrid query, 1.7ms

The Numbers

End-to-end performance from the benchmark run.

5,000 products loaded into SwarnDB

283 vec/sec

17.6 sec

Customers Also Bought (20 products)

0.6ms

Cross-category co-purchase reach

all 8

Network: 500 products across 8 categories

3 hops

2.3ms

Price-filtered recs ($20-$50)

one call

7.4ms

Full query (yoga mat, 200 products)

2.7ms

Hybrid query (10 results)

1.7ms

The Code

Everything above, in a few lines of Python.

python
from swarndb import SwarnDBClient
from swarndb.search import Filter

client = SwarnDBClient(host="localhost", port=50051)

# "Also bought" is a typed edge derived from orders, with provenance.
client.graph.put_edge("products", source=speaker_id, target=dress_id,
                      edge_type="BOUGHT_WITH",
                      provenance={"source": "orders", "co_count": 312})
client.graph.bulk_import_edges("products", copurchase_rows, format="csv")

# Price-filtered recommendations: scope by structure, rank by meaning (7.4ms)
recs = (
    client.graph.query("products")
    .vector_similar(speaker_embedding, k=50)
    .traverse("BOUGHT_WITH", direction="outgoing")
    .vector_rank(speaker_embedding, k=10)
    .return_nodes()
)

# Filter-then-search: the true top-k among in-budget products
filtered = client.search.query("products",
    vector=speaker_embedding, k=10,
    filter=Filter.between("price", 20.0, 50.0)
)

Try it yourself

Clone the repo, spin up SwarnDB, and run this showcase in minutes.

View on GitHub