optimize search query + fix sentry

This commit is contained in:
Cat /dev/Nulo 2024-09-16 21:53:47 -03:00
parent 9fced663ff
commit 841a1412a1

View file

@ -1,22 +1,10 @@
import { db } from '$lib/server/db'; import { db } from '$lib/server/db';
import * as schema from '$lib/server/db/schema';
import { sql } from 'drizzle-orm'; import { sql } from 'drizzle-orm';
import type { PageServerLoad } from './$types'; import type { PageServerLoad } from './$types';
import * as Sentry from '@sentry/sveltekit'; import * as Sentry from '@sentry/sveltekit';
export const load: PageServerLoad = async ({ params, setHeaders }) => { export const load: PageServerLoad = async ({ params, setHeaders }) => {
// const latestDatasetsSq = db.$with('latest_datasets').as(
// db.select({
// id: datasets.id,
// }).from(datasets)
// .innerJoin(
// db.select({
// id_comercio: datasets.id_comercio,
// max_date: max(datasets.date),
// }).from(d2).groupBy(datasets.id_comercio),
// and(eq(datasets.id_comercio, d2.id_comercio), eq(datasets.date, d2.max_date))
// // 'datasets.id_comercio = latest_datasets.id_comercio AND datasets.date = latest_datasets.max_date'
// ))
const query = params.query const query = params.query
.replaceAll(/á/giu, 'a') .replaceAll(/á/giu, 'a')
.replaceAll(/é/giu, 'e') .replaceAll(/é/giu, 'e')
@ -24,8 +12,12 @@ export const load: PageServerLoad = async ({ params, setHeaders }) => {
.replaceAll(/ó/giu, 'o') .replaceAll(/ó/giu, 'o')
.replaceAll(/ú/giu, 'u') .replaceAll(/ú/giu, 'u')
.replaceAll(/ñ/giu, 'n'); .replaceAll(/ñ/giu, 'n');
const productosQuery = sql` const productosQuery = db
SELECT id_producto, productos_descripcion, productos_marca, .select({
id_producto: schema.productos_descripcion_index.id_producto,
productos_descripcion: schema.productos_descripcion_index.productos_descripcion,
productos_marca: schema.productos_descripcion_index.productos_marca,
in_datasets_count: sql<number>`
(WITH latest_datasets AS ( (WITH latest_datasets AS (
SELECT d1.id SELECT d1.id
FROM datasets d1 FROM datasets d1
@ -37,32 +29,26 @@ export const load: PageServerLoad = async ({ params, setHeaders }) => {
)SELECT COUNT(DISTINCT p.id_dataset) as dataset_count )SELECT COUNT(DISTINCT p.id_dataset) as dataset_count
FROM precios p FROM precios p
JOIN latest_datasets ld ON p.id_dataset = ld.id JOIN latest_datasets ld ON p.id_dataset = ld.id
WHERE p.id_producto = index.id_producto) as in_datasets_count WHERE p.id_producto = productos_descripcion_index.id_producto)`.as('in_datasets_count')
FROM productos_descripcion_index index })
WHERE productos_descripcion ILIKE ${`%${query}%`} .from(schema.productos_descripcion_index)
ORDER BY in_datasets_count desc .where(sql`productos_descripcion ILIKE ${`%${query}%`}`)
LIMIT 100 .orderBy(sql`in_datasets_count desc`)
`; .limit(100);
const productos = await Sentry.startSpan( const productos = await Sentry.startSpan(
{ {
op: 'db.query', op: 'db.query',
name: productosQuery, name: productosQuery.toSQL().sql,
data: { 'db.system': 'postgresql' } data: { 'db.system': 'postgresql' }
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
} as any, } as any,
() => () => productosQuery
db.execute<{
id_producto: string;
productos_descripcion: string;
productos_marca: string | null;
in_datasets_count: number;
}>(productosQuery)
); );
const collapsedProductos = productos.reduce( const collapsedProductos = productos.reduce(
(acc, producto) => { (acc, producto) => {
const existingProduct = acc.find((p) => p.id_producto === producto.id_producto); const existingProduct = acc.find((p) => BigInt(p.id_producto) === producto.id_producto);
if (existingProduct) { if (existingProduct) {
existingProduct.descriptions.push(producto.productos_descripcion); existingProduct.descriptions.push(producto.productos_descripcion!);
if (producto.productos_marca) existingProduct.marcas.add(producto.productos_marca); if (producto.productos_marca) existingProduct.marcas.add(producto.productos_marca);
existingProduct.in_datasets_count = Math.max( existingProduct.in_datasets_count = Math.max(
existingProduct.in_datasets_count, existingProduct.in_datasets_count,
@ -70,8 +56,8 @@ WHERE p.id_producto = index.id_producto) as in_datasets_count
); );
} else { } else {
acc.push({ acc.push({
id_producto: producto.id_producto, id_producto: producto.id_producto!.toString(),
descriptions: [producto.productos_descripcion], descriptions: [producto.productos_descripcion!],
marcas: new Set(producto.productos_marca ? [producto.productos_marca] : []), marcas: new Set(producto.productos_marca ? [producto.productos_marca] : []),
in_datasets_count: producto.in_datasets_count in_datasets_count: producto.in_datasets_count
}); });
@ -90,63 +76,5 @@ WHERE p.id_producto = index.id_producto) as in_datasets_count
'Cache-Control': 'public, max-age=600' 'Cache-Control': 'public, max-age=600'
}); });
// 'latest_datasets',
// sql`
// WITH latest_datasets AS (
// SELECT d1.id
// FROM datasets d1
// JOIN (
// SELECT id_comercio, MAX(date) as max_date
// FROM datasets
// GROUP BY id_comercio
// ) d2 ON d1.id_comercio = d2.id_comercio AND d1.date = d2.max_date
// )`
// .select({
// id_producto: productos_descripcion_index.id_producto,
// productos_descripcion: productos_descripcion_index.productos_descripcion,
// productos_marca: productos_descripcion_index.productos_marca,
// })
// .from(productos_descripcion_index)
// .where(ilike(productos_descripcion_index.productos_descripcion, `%${query}%`))
// .orderBy(sql`
// WITH latest_datasets AS (
// SELECT d1.id
// FROM datasets d1
// JOIN (
// SELECT id_comercio, MAX(date) as max_date
// FROM datasets
// GROUP BY id_comercio
// ) d2 ON d1.id_comercio = d2.id_comercio AND d1.date = d2.max_date
// )
// SELECT COUNT(DISTINCT p.id_dataset) as dataset_count
// FROM precios p
// JOIN latest_datasets ld ON p.id_dataset = ld.id
// WHERE p.id_producto = ${productos_descripcion_index.id_producto}`);
return { productos, collapsedProductos, query }; return { productos, collapsedProductos, query };
// const precios = await sql<
// {
// id_producto: string;
// productos_precio_lista: number;
// productos_descripcion: string;
// }[]
// >`
// WITH latest_prices AS (
// SELECT DISTINCT ON (id_comercio, id_producto)
// id_comercio,
// id_producto,
// productos_precio_lista,
// productos_descripcion
// FROM precios
// )
// SELECT
// id_producto,
// productos_precio_lista,
// productos_descripcion
// FROM latest_prices
// WHERE productos_descripcion ILIKE ${`%${query}%`}
// `;
// return {
// precios
// };
}; };