AI infrastructure
3,072-dimension embeddings: the maths under GoGee's product search
Semantic search is only as good as its vector layer, and vector layers are where most implementations quietly cut corners, smaller models, truncated dimensions, no index, or a similarity threshold set so low that everything matches everything.
This article documents exactly how GoGee's is built, because it is the shared foundation for text search, photo search and voice search alike.
GoGee feature series · 4 of 33
How it's actually built
- Embedding model
- google/gemini-embedding-001
- Dimensions
- 3,072 native (no truncation)
- Storage type
- halfvec(3072) on the product row
- Index
- HNSW, halfvec cosine operators
- Distance
- Cosine, exposed as 1 − distance similarity
- Default floor
- 0.15, raised to 0.25–0.35 for stricter queries
- 01Input
Product record
Name, attributes and imagery
- 02AI
Embed
gemini-embedding-001 at 3,072 native dimensions
- 03Database
Store
halfvec(3072) column on the product row
- 04Database
Index
HNSW with halfvec cosine operators
- 05Output
Similarity lookup
Cosine distance exposed as 1 − distance
Guardrails and fallbacks
- 0.15 default floor
- 0.25–0.35 for stricter queries
- No dimension truncation
3,072-dim product embeddings, data flow, generated from the shared GoGee feature diagram template.
Why 3,072 dimensions, stored as halfvec
The catalogue started on a 1,536-dimension vector column and was migrated to 3,072 dimensions using the half-precision vector type. Higher dimensionality preserves more nuance between products that differ in one attribute, a 5-litre versus 10-litre version of the same item, while half-precision storage keeps the index small enough to stay fast.
The index is HNSW with cosine operators, which is what allows an approximate nearest-neighbour lookup across thousands of SKUs to return inside a page load rather than a spinner.
What actually gets embedded
A product is embedded from a composed text blob rather than its name alone: product name, AI-enhanced name, short and long descriptions, supplier attributes, colours, materials and styles, category names, custom fields, variant labels and SKU. Where product photos have been captioned by the vision model, that caption is included as a visual description line.
This is the single biggest lever on search quality. Thin product data produces thin vectors, and no model choice compensates for a catalogue where half the products have a name and nothing else. It is also why the catalogue-content tooling and the search tooling are sold as one platform rather than two.
The similarity function is a database function
Matching happens in Postgres through a similarity RPC that accepts the query vector, a match count, a minimum similarity, and optional category, brand and price-range filters. It returns products with a similarity value computed as one minus cosine distance.
Because filtering happens inside the same query as the vector match, a price bound or category restriction narrows the candidate set at the database level instead of being applied to an already-truncated result page, which is the usual reason vector search appears to "ignore" filters.
- Threshold is per-call: looser for photo search, stricter for feature-specific queries
- Refinement passes can drop the floor to zero and re-rank within a known set
- Category, brand and price filters are arguments to the match function itself
Embeddings are generated in controlled batches
Vectors are produced by an admin-triggered batch job that selects candidate products, builds the text blob, embeds them and writes the vector plus a timestamp back to the product row. Because the timestamp is stored, re-embedding can target only products whose content changed since they were last embedded.
That is deliberate rather than lazy: a database trigger firing an AI call on every product edit is how clients end up with unpredictable AI bills during a bulk import of 40,000 rows.
Questions we get asked
Do you re-embed the whole catalogue every time?
No. Each product stores when it was last embedded, so batches can target only new or changed products.
Is this a separate vector database?
No. Vectors live in the same Postgres database as your products, which is why filters, stock and pricing can be applied in the same query as the similarity match.
Does image search use image embeddings?
Not at query time. Photos are captioned by a vision model and the caption is embedded with the same text-embedding model, so both search modes share one index.
Read next
AI search
AI text search, semantic, not keyword
How GoGee's AI text search works: Gemini extracts structured filters, queries are embedded and matched with co…
AI search
AI image search, snap & find
GoGee's photo search reads the image with a vision model, resolves brand and barcode, then ranks catalogue mat…
Ecommerce
Product catalogue at scale
How GoGee models thousands of SKUs: variant rows, quantity-break price tiers, role-gated business pricing and …

