Skip to main content

Flow: Recommendations

Product recommendation endpoints served by the search proxy. Includes similar products, search suggestions, and personalized recommendations.

Request Path

Endpoints

EndpointPurposeKey Input
POST /api/v1/indexes/:index/recommendations/similarProducts like thesedocumentIds[] (1-10)
POST /api/v1/indexes/:index/recommendations/complementaryProducts that pair welldocumentIds[] (not yet implemented)
POST /api/v1/indexes/:index/recommendations/queriesSearch suggestions / autocompleteq (query prefix)
POST /api/v1/indexes/:index/recommendations/for-youPersonalized recommendationsuserId (required)

Similar Products

Where: components/search_proxy/src/recommendations.ts

How It Works

  1. Splits documentIds into up to 6 arrays (Cloudflare concurrent connection limit)
  2. Sends parallel context searches to Marqo using HYBRID search with tensor ranking
  3. Each search uses document context (the seed products) with excludeInputDocuments: true
  4. Results interleaved and deduplicated by _id and collapseFields

Marqo request key params:

{
"searchMethod": "HYBRID",
"hybridParameters": { "retrievalMethod": "tensor", "rankingMethod": "tensor" },
"context": { "documents": { "ids": { "doc_id": 1 } } }
}

Logs:

{"message": "marqo_context_search_request", "url": "..."}
{"message": "marqo_search_response", "hitsCount": 10, "processingTimeMs": 30}

Search Suggestions

Where: components/search_proxy/src/recommendations.ts

Calls Marqo's search suggestions API with:

  • q — query prefix
  • fuzzyEditDistance — typo tolerance (default 0)
  • minFuzzyMatchLength — minimum chars for fuzzy (default 3)
  • Config from search_suggestions_config in settings

Returns: { suggestions: [{ suggestion, score }] }

Personalized (For-You)

Where: components/search_proxy/src/recommendations.ts

How It Works

  1. Requires pixel_id in settings (400 error if not configured)
  2. Pixel Worker RPC: env.PIXEL_WORKER.getPersonalizationData(pixelId, userId, sessionId) — fetches tracked events (clicks, add-to-cart, purchases)
  3. Optional filter by interactionTypes (ClickEvent, AddToCartEvent, PurchaseEvent)
  4. Takes first 60 document IDs from tracked events
  5. Runs same parallel context search as similar products

Fallback: If no tracked events found → NoTrackedEventsError caught → falls back to wildcard search (q: "*") with any provided filters. Returns general products instead of failure.

Inspect: Pixel Worker is a separate Cloudflare Worker bound via service binding. Check its logs:

npx wrangler tail pixel-ingestion-worker-{env_suffix}

What to Look For

SymptomWhere to Check
401 on recommendationsSame auth as search — see Search.
404 "Not configured"Settings not in KV. Check Settings Sync.
Similar returns no resultsSeed documents exist in index? Check filter expression.
Complementary returns 400Expected — not yet implemented.
Suggestions returning nothingIndex has searchable text? Check search_suggestions_config.
For-you returning generic resultsNo tracked events for userId (falls back to wildcard q: "*" search). Check Pixel Worker logs.
For-you returning 400pixel_id not configured in index settings. Check Settings Sync.
Slow recommendationsMultiple parallel Marqo calls. Check per-call processingTimeMs.