From 341950bc2c2021be9963d6fa3e1e11dfac10b1a0 Mon Sep 17 00:00:00 2001 From: Ethan Niser Date: Sun, 20 Oct 2024 21:53:00 -0400 Subject: [PATCH] wip --- src/app/api/search/route.ts | 68 ++++++++++--------------------------- src/db/schema.ts | 7 ++-- 2 files changed, 21 insertions(+), 54 deletions(-) diff --git a/src/app/api/search/route.ts b/src/app/api/search/route.ts index f14b3e6..9c83810 100644 --- a/src/app/api/search/route.ts +++ b/src/app/api/search/route.ts @@ -5,7 +5,7 @@ import { subcategories, subcollection, } from "@/db/schema"; -import { sql } from "drizzle-orm"; +import { ilike, sql } from "drizzle-orm"; import { NextRequest } from "next/server"; export async function GET(request: NextRequest) { @@ -15,55 +15,23 @@ export async function GET(request: NextRequest) { return Response.json([]); } - let results; - - if (searchTerm.length <= 2) { - // If the search term is short (e.g., "W"), use ILIKE for prefix matching - results = await db - .select() - .from(products) - .where(sql`${products.name} ILIKE ${searchTerm + "%"}`) // Prefix match - .limit(5) - .innerJoin( - subcategories, - sql`${products.subcategory_slug} = ${subcategories.slug}`, - ) - .innerJoin( - subcollection, - sql`${subcategories.subcollection_id} = ${subcollection.id}`, - ) - .innerJoin( - categories, - sql`${subcollection.category_slug} = ${categories.slug}`, - ); - } else { - // For longer search terms, use full-text search with tsquery - const formattedSearchTerm = searchTerm - .split(" ") - .filter((term) => term.trim() !== "") // Filter out empty terms - .map((term) => `${term}:*`) - .join(" & "); - - results = await db - .select() - .from(products) - .where( - sql`to_tsvector('english', ${products.name}) @@ to_tsquery('english', ${formattedSearchTerm})`, - ) - .limit(5) - .innerJoin( - subcategories, - sql`${products.subcategory_slug} = ${subcategories.slug}`, - ) - .innerJoin( - subcollection, - sql`${subcategories.subcollection_id} = ${subcollection.id}`, - ) - .innerJoin( - categories, - sql`${subcollection.category_slug} = ${categories.slug}`, - ); - } + const results = await db + .select() + .from(products) + .where(ilike(products.name, `%${searchTerm}%`)) + .limit(5) + .innerJoin( + subcategories, + sql`${products.subcategory_slug} = ${subcategories.slug}`, + ) + .innerJoin( + subcollection, + sql`${subcategories.subcollection_id} = ${subcollection.id}`, + ) + .innerJoin( + categories, + sql`${subcollection.category_slug} = ${categories.slug}`, + ); const searchResults: ProductSearchResult = results.map((item) => { const href = `/products/${item.categories.slug}/${item.subcategories.slug}/${item.products.slug}`; diff --git a/src/db/schema.ts b/src/db/schema.ts index 320fc67..366198a 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -63,10 +63,9 @@ export const products = pgTable( image_url: text("image_url"), }, (table) => ({ - nameSearchIndex: index("name_search_index").using( - "gin", - sql`to_tsvector('english', ${table.name})`, - ), + nameSearchIndex: index("name_search_index") + .using("gin", sql`${table.name}`, sql`gi`, sql`n_trgm_ops`) + .concurrently(), }), );