groceries: relevance-ranked search (plain/basic products first)
All checks were successful
Deploy production / deploy (push) Successful in 1m13s
All checks were successful
Deploy production / deploy (push) Successful in 1m13s
- search.ts: score on the core name (brand/size stripped): exact or query+base suffix (kipdij+filet), head-final compounds, prefix, inside; penalties per extra word and per flavour/processing word (search-words.ts, editable); bonuses for store brands, the query's dominant category, store count, favourites; trigram tiebreak - groceries.synonyms table (seeded: kipdij/kippendij, pasta → spaghetti, …) expands queries - list rows show all pack sizes of a group; group picker uses the same ranking - scripts/groceries-search-eval.ts prints top results + latency; preflight now 8 tables
This commit is contained in:
@@ -256,8 +256,30 @@ export const groceryImportRuns = groceriesSchema.table(
|
||||
(t) => [index('import_runs_store_idx').on(t.storeId, t.startedAt)]
|
||||
);
|
||||
|
||||
/**
|
||||
* Search synonyms (search.ts): a query word `term` also finds products with `synonym`.
|
||||
* One-directional (pasta → spaghetti); spelling variants are stored both ways. Folded,
|
||||
* lower-case words; edits apply within 5 minutes (cached).
|
||||
*/
|
||||
export const grocerySynonyms = groceriesSchema.table(
|
||||
'synonyms',
|
||||
{
|
||||
id: id(),
|
||||
term: text('term').notNull(),
|
||||
synonym: text('synonym').notNull(),
|
||||
...timestamps
|
||||
},
|
||||
(t) => [
|
||||
uniqueIndex('synonyms_term_synonym_key').on(t.term, t.synonym),
|
||||
check('synonyms_term_check', sql`${t.term} ~ '^[a-z0-9][a-z0-9 -]{0,40}$'`),
|
||||
check('synonyms_synonym_check', sql`${t.synonym} ~ '^[a-z0-9][a-z0-9 -]{0,40}$'`),
|
||||
check('synonyms_not_self', sql`${t.term} <> ${t.synonym}`)
|
||||
]
|
||||
);
|
||||
|
||||
export type GroceryStore = typeof groceryStores.$inferSelect;
|
||||
export type GroceryGroup = typeof groceryGroups.$inferSelect;
|
||||
export type GroceryItem = typeof groceryItems.$inferSelect;
|
||||
export type GroceryCategory = typeof groceryCategories.$inferSelect;
|
||||
export type GroceryManualPrice = typeof groceryManualPrices.$inferSelect;
|
||||
export type GrocerySynonym = typeof grocerySynonyms.$inferSelect;
|
||||
|
||||
Reference in New Issue
Block a user