Bonsai Search Manager

← Back

Index Status

πŸ“Š
Bonsai Index
Current document count and connection status
Connecting…

Seed Staple Products

πŸ“¦
Seed Staples
Index products from standard grocery categories into Bonsai
How it works:
Each staple fetches a fixed batch size (Coffee=60, Milk=40, Bread=40, others=30) ordered by product_id ASC.
Page 0 = rows 1–60. Page 1 = rows 61–120. And so on β€” new products always get higher IDs so they're never skipped.
Seeding is sequential (coffee β†’ banana β†’ milk…). Re-seeding the same page upserts β€” no duplicates.
Set From = To to seed a single page. Set To higher to auto-loop through multiple pages (e.g. 0 β†’ 24 indexes all 1,482 coffee products). The numbers in brackets are products per page per category.

Search & Index by Name

πŸ”Ž
Index by Product Name
Search CockroachDB by product name keywords and index matching products

Full Product Index

πŸ—„οΈ
Full Index (All Products)
Index every product in the database in batches of 100. Resumes from the last processed ID.
Starting…

Test Search

πŸ”
Search Bonsai Index
Query the Bonsai index to test relevance and ranking

How Search Works

πŸ”„
Backend Search Pipeline
Two-step flow: Bonsai (Elasticsearch) for relevance ranking β†’ CockroachDB for live prices.
Step 1 β€” Autocomplete (optional)
GET /api/bonsai/suggest?q=coffee
As the user types, the API queries Bonsai aggregations for matching categories and brands, and concurrently fetches live completions from Woolworths + Coles (merged and deduplicated internally β€” sources not exposed). The dropdown shows up to 12 term suggestions + 8 categories + 6 brands.
Step 2 β€” Bonsai Search (Elasticsearch)
POST /api/bonsai/search { query, size, offset, filter? }
Runs a function_score query across product_name (Γ—5), ai_keywords (Γ—3), product_category2 (Γ—2), searchable_text (Γ—1). Boosted by brand_boost_factor and priority_score stored per document. Results are collapsed on product_name so each product appears once even if indexed for multiple supermarkets. Pinned products are injected at their fixed ranks before the response is returned. Returns { total, hits: [{ product_id, product_name, product_brand, supermarkets, pinned? … }] }
Step 3 β€” CockroachDB Price Lookup
POST /api/products/details { product_ids, store_ids, store_map }
Takes the product_ids from Step 2 and queries CockroachDB across four joined tables: product_details Β· product_attributes Β· product_categories Β· product_price. Products are grouped by EAN (same physical product across chains), so Woolworths + Coles variants of the same item appear on one card. For each selected store_id, the response includes a price row (or a null row if not available at that store). Results are re-sorted client-side to match Bonsai relevance order before rendering.
Featured / Default Products
GET /api/bonsai/featured
Returns up to 20 curated products ordered by rank. Bonsai document metadata is merged with live prices from CockroachDB. Suitable for use as a homepage or "default" product list by external clients β€” no internal fields exposed. Manage via the Featured Products section below (add from search results using ⭐ Feature).

Product Card Preview

πŸƒ
Featured Products Preview
Live products from GET /api/bonsai/featured β€” max 20. Search for a product above and click ⭐ Feature to add. Adjust rank inline.
Stores shown:

Store Details

πŸ“
Store Sync
Sync store records from CockroachDB into Cloudflare D1 for fast edge lookups. D1 is the read cache β€” CockroachDB is source of truth. Duplicates are handled by upsert on store_id.
Loading…
Sync one chain at a time or all at once. Each sync call fetches 200 stores per page from CockroachDB and upserts them into D1.
Browse D1 Stores
No stores in D1 yet β€” sync first.

Search Pins

πŸ“Œ
Pinned Products
Force specific products to fixed positions for a query. Click "πŸ“Œ Pin" on any search result to pin it.
No pins yet β€” search for products above and click πŸ“Œ Pin to add one.

Featured / Default Products

⭐
Featured Products
Curated products shown when the search box is empty. Organised by category (milk, bread, coffee…). Called externally as GET /api/bonsai/featured.