mirror of
https://github.com/catdevnull/preciazo.git
synced 2024-11-26 11:36:20 +00:00
Compare commits
No commits in common. "5b132db15e39a13da3019a6fb1bfe506cd5aff09" and "d685ef8f758c45d31f8addf2aa6758c0014a0521" have entirely different histories.
5b132db15e
...
d685ef8f75
8 changed files with 102 additions and 501 deletions
4
.github/workflows/sepa-precios-archiver.yml
vendored
4
.github/workflows/sepa-precios-archiver.yml
vendored
|
@ -27,8 +27,10 @@ jobs:
|
||||||
B2_BUCKET_NAME: ${{ secrets.B2_BUCKET_NAME }}
|
B2_BUCKET_NAME: ${{ secrets.B2_BUCKET_NAME }}
|
||||||
B2_BUCKET_KEY_ID: ${{ secrets.B2_BUCKET_KEY_ID }}
|
B2_BUCKET_KEY_ID: ${{ secrets.B2_BUCKET_KEY_ID }}
|
||||||
B2_BUCKET_KEY: ${{ secrets.B2_BUCKET_KEY }}
|
B2_BUCKET_KEY: ${{ secrets.B2_BUCKET_KEY }}
|
||||||
DATOS_PRODUCCION_GOB_AR: https://proxy-datos-produccion-gob-ar.nulo.in
|
|
||||||
run: |
|
run: |
|
||||||
|
# usar un servidor especifico porque parece que a veces
|
||||||
|
# bloquean el acceso desde afuera del país
|
||||||
|
sudo echo "190.2.53.185 datos.produccion.gob.ar" | sudo tee -a /etc/hosts
|
||||||
cd sepa
|
cd sepa
|
||||||
bun install --frozen-lockfile
|
bun install --frozen-lockfile
|
||||||
bun archiver.ts
|
bun archiver.ts
|
||||||
|
|
|
@ -23,11 +23,6 @@ const B2_BUCKET_NAME = checkEnvVariable("B2_BUCKET_NAME");
|
||||||
const B2_BUCKET_KEY_ID = checkEnvVariable("B2_BUCKET_KEY_ID");
|
const B2_BUCKET_KEY_ID = checkEnvVariable("B2_BUCKET_KEY_ID");
|
||||||
const B2_BUCKET_KEY = checkEnvVariable("B2_BUCKET_KEY");
|
const B2_BUCKET_KEY = checkEnvVariable("B2_BUCKET_KEY");
|
||||||
|
|
||||||
const DATOS_PRODUCCION_GOB_AR =
|
|
||||||
process.env.DATOS_PRODUCCION_GOB_AR || "https://datos.produccion.gob.ar";
|
|
||||||
const processUrl = (url: string) =>
|
|
||||||
url.replace(/^https:\/\/datos\.produccion\.gob\.ar/, DATOS_PRODUCCION_GOB_AR);
|
|
||||||
|
|
||||||
const s3 = new S3Client({
|
const s3 = new S3Client({
|
||||||
endpoint: "https://s3.us-west-004.backblazeb2.com",
|
endpoint: "https://s3.us-west-004.backblazeb2.com",
|
||||||
region: "us-west-004",
|
region: "us-west-004",
|
||||||
|
@ -39,10 +34,7 @@ const s3 = new S3Client({
|
||||||
|
|
||||||
async function getRawDatasetInfo(attempts = 0) {
|
async function getRawDatasetInfo(attempts = 0) {
|
||||||
try {
|
try {
|
||||||
const url = processUrl(
|
return await $`curl -L https://datos.produccion.gob.ar/api/3/action/package_show?id=sepa-precios`.json();
|
||||||
"https://datos.produccion.gob.ar/api/3/action/package_show?id=sepa-precios"
|
|
||||||
);
|
|
||||||
return await $`curl -L ${url}`.json();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (attempts >= 4) {
|
if (attempts >= 4) {
|
||||||
console.error(`❌ Error fetching dataset info`, error);
|
console.error(`❌ Error fetching dataset info`, error);
|
||||||
|
@ -145,8 +137,7 @@ for (const resource of datasetInfo.result.resources) {
|
||||||
console.info(dir);
|
console.info(dir);
|
||||||
try {
|
try {
|
||||||
const zip = join(dir, "zip");
|
const zip = join(dir, "zip");
|
||||||
const url = processUrl(resource.url);
|
await $`curl --retry 8 --retry-delay 5 --retry-all-errors -L -o ${zip} ${resource.url}`;
|
||||||
await $`curl --retry 8 --retry-delay 5 --retry-all-errors -L -o ${zip} ${url}`;
|
|
||||||
await $`unzip ${zip} -d ${dir}`;
|
await $`unzip ${zip} -d ${dir}`;
|
||||||
await rm(zip);
|
await rm(zip);
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { max, relations, sql } from "drizzle-orm";
|
import { max, relations } from "drizzle-orm";
|
||||||
import {
|
import {
|
||||||
pgTable,
|
pgTable,
|
||||||
integer,
|
integer,
|
||||||
|
@ -179,11 +179,5 @@ export const productos_descripcion_index = pgTable(
|
||||||
id_producto: bigint("id_producto", { mode: "bigint" }),
|
id_producto: bigint("id_producto", { mode: "bigint" }),
|
||||||
productos_descripcion: text("productos_descripcion").unique(),
|
productos_descripcion: text("productos_descripcion").unique(),
|
||||||
productos_marca: text("productos_marca"),
|
productos_marca: text("productos_marca"),
|
||||||
},
|
}
|
||||||
(table) => ({
|
|
||||||
// https://orm.drizzle.team/learn/guides/postgresql-full-text-search
|
|
||||||
tableSearchIndex: index(
|
|
||||||
"productos_descripcion_index_search_descripcion"
|
|
||||||
).using("gin", sql`to_tsvector('spanish', ${table.productos_descripcion})`),
|
|
||||||
})
|
|
||||||
);
|
);
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
CREATE INDEX IF NOT EXISTS "productos_descripcion_index_search_descripcion" ON "productos_descripcion_index" USING gin (to_tsvector('spanish', "productos_descripcion"));
|
|
|
@ -1,446 +0,0 @@
|
||||||
{
|
|
||||||
"id": "36a04e5e-b070-4b89-96ce-e9431c2f199b",
|
|
||||||
"prevId": "7ea9c123-4d12-4f0b-9452-e8952462fbf8",
|
|
||||||
"version": "7",
|
|
||||||
"dialect": "postgresql",
|
|
||||||
"tables": {
|
|
||||||
"public.datasets": {
|
|
||||||
"name": "datasets",
|
|
||||||
"schema": "",
|
|
||||||
"columns": {
|
|
||||||
"id": {
|
|
||||||
"name": "id",
|
|
||||||
"type": "serial",
|
|
||||||
"primaryKey": true,
|
|
||||||
"notNull": true
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
"name": "name",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"date": {
|
|
||||||
"name": "date",
|
|
||||||
"type": "date",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"id_comercio": {
|
|
||||||
"name": "id_comercio",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {},
|
|
||||||
"foreignKeys": {},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {
|
|
||||||
"datasets_name_key": {
|
|
||||||
"name": "datasets_name_key",
|
|
||||||
"nullsNotDistinct": false,
|
|
||||||
"columns": [
|
|
||||||
"name"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"public.precios": {
|
|
||||||
"name": "precios",
|
|
||||||
"schema": "",
|
|
||||||
"columns": {
|
|
||||||
"id_dataset": {
|
|
||||||
"name": "id_dataset",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"id_comercio": {
|
|
||||||
"name": "id_comercio",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"id_bandera": {
|
|
||||||
"name": "id_bandera",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"id_sucursal": {
|
|
||||||
"name": "id_sucursal",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"id_producto": {
|
|
||||||
"name": "id_producto",
|
|
||||||
"type": "bigint",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_ean": {
|
|
||||||
"name": "productos_ean",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_descripcion": {
|
|
||||||
"name": "productos_descripcion",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_cantidad_presentacion": {
|
|
||||||
"name": "productos_cantidad_presentacion",
|
|
||||||
"type": "numeric(10, 2)",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_unidad_medida_presentacion": {
|
|
||||||
"name": "productos_unidad_medida_presentacion",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_marca": {
|
|
||||||
"name": "productos_marca",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_precio_lista": {
|
|
||||||
"name": "productos_precio_lista",
|
|
||||||
"type": "numeric(10, 2)",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_precio_referencia": {
|
|
||||||
"name": "productos_precio_referencia",
|
|
||||||
"type": "numeric(10, 2)",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_cantidad_referencia": {
|
|
||||||
"name": "productos_cantidad_referencia",
|
|
||||||
"type": "numeric(10, 2)",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_unidad_medida_referencia": {
|
|
||||||
"name": "productos_unidad_medida_referencia",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_precio_unitario_promo1": {
|
|
||||||
"name": "productos_precio_unitario_promo1",
|
|
||||||
"type": "numeric(10, 2)",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_leyenda_promo1": {
|
|
||||||
"name": "productos_leyenda_promo1",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_precio_unitario_promo2": {
|
|
||||||
"name": "productos_precio_unitario_promo2",
|
|
||||||
"type": "numeric(10, 2)",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_leyenda_promo2": {
|
|
||||||
"name": "productos_leyenda_promo2",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {
|
|
||||||
"idx_precios_id_producto": {
|
|
||||||
"name": "idx_precios_id_producto",
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"expression": "id_producto",
|
|
||||||
"isExpression": false,
|
|
||||||
"asc": true,
|
|
||||||
"nulls": "last"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"isUnique": false,
|
|
||||||
"concurrently": false,
|
|
||||||
"method": "btree",
|
|
||||||
"with": {}
|
|
||||||
},
|
|
||||||
"idx_precios_id_producto_id_dataset": {
|
|
||||||
"name": "idx_precios_id_producto_id_dataset",
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"expression": "id_producto",
|
|
||||||
"isExpression": false,
|
|
||||||
"asc": true,
|
|
||||||
"nulls": "last"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"expression": "id_dataset",
|
|
||||||
"isExpression": false,
|
|
||||||
"asc": true,
|
|
||||||
"nulls": "last"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"isUnique": false,
|
|
||||||
"concurrently": false,
|
|
||||||
"method": "btree",
|
|
||||||
"with": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"foreignKeys": {
|
|
||||||
"precios_id_dataset_datasets_id_fk": {
|
|
||||||
"name": "precios_id_dataset_datasets_id_fk",
|
|
||||||
"tableFrom": "precios",
|
|
||||||
"tableTo": "datasets",
|
|
||||||
"columnsFrom": [
|
|
||||||
"id_dataset"
|
|
||||||
],
|
|
||||||
"columnsTo": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"onDelete": "no action",
|
|
||||||
"onUpdate": "no action"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {}
|
|
||||||
},
|
|
||||||
"public.productos_descripcion_index": {
|
|
||||||
"name": "productos_descripcion_index",
|
|
||||||
"schema": "",
|
|
||||||
"columns": {
|
|
||||||
"id_producto": {
|
|
||||||
"name": "id_producto",
|
|
||||||
"type": "bigint",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_descripcion": {
|
|
||||||
"name": "productos_descripcion",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"productos_marca": {
|
|
||||||
"name": "productos_marca",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {
|
|
||||||
"productos_descripcion_index_search_descripcion": {
|
|
||||||
"name": "productos_descripcion_index_search_descripcion",
|
|
||||||
"columns": [
|
|
||||||
{
|
|
||||||
"expression": "to_tsvector('spanish', \"productos_descripcion\")",
|
|
||||||
"asc": true,
|
|
||||||
"isExpression": true,
|
|
||||||
"nulls": "last"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"isUnique": false,
|
|
||||||
"concurrently": false,
|
|
||||||
"method": "gin",
|
|
||||||
"with": {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"foreignKeys": {},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {
|
|
||||||
"productos_descripcion_index_productos_descripcion_unique": {
|
|
||||||
"name": "productos_descripcion_index_productos_descripcion_unique",
|
|
||||||
"nullsNotDistinct": false,
|
|
||||||
"columns": [
|
|
||||||
"productos_descripcion"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"public.sucursales": {
|
|
||||||
"name": "sucursales",
|
|
||||||
"schema": "",
|
|
||||||
"columns": {
|
|
||||||
"id_dataset": {
|
|
||||||
"name": "id_dataset",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"id_comercio": {
|
|
||||||
"name": "id_comercio",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"id_bandera": {
|
|
||||||
"name": "id_bandera",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"id_sucursal": {
|
|
||||||
"name": "id_sucursal",
|
|
||||||
"type": "integer",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_nombre": {
|
|
||||||
"name": "sucursales_nombre",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_tipo": {
|
|
||||||
"name": "sucursales_tipo",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_calle": {
|
|
||||||
"name": "sucursales_calle",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_numero": {
|
|
||||||
"name": "sucursales_numero",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_latitud": {
|
|
||||||
"name": "sucursales_latitud",
|
|
||||||
"type": "numeric",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_longitud": {
|
|
||||||
"name": "sucursales_longitud",
|
|
||||||
"type": "numeric",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_observaciones": {
|
|
||||||
"name": "sucursales_observaciones",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_barrio": {
|
|
||||||
"name": "sucursales_barrio",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_codigo_postal": {
|
|
||||||
"name": "sucursales_codigo_postal",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_localidad": {
|
|
||||||
"name": "sucursales_localidad",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_provincia": {
|
|
||||||
"name": "sucursales_provincia",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_lunes_horario_atencion": {
|
|
||||||
"name": "sucursales_lunes_horario_atencion",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_martes_horario_atencion": {
|
|
||||||
"name": "sucursales_martes_horario_atencion",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_miercoles_horario_atencion": {
|
|
||||||
"name": "sucursales_miercoles_horario_atencion",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_jueves_horario_atencion": {
|
|
||||||
"name": "sucursales_jueves_horario_atencion",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_viernes_horario_atencion": {
|
|
||||||
"name": "sucursales_viernes_horario_atencion",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_sabado_horario_atencion": {
|
|
||||||
"name": "sucursales_sabado_horario_atencion",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
},
|
|
||||||
"sucursales_domingo_horario_atencion": {
|
|
||||||
"name": "sucursales_domingo_horario_atencion",
|
|
||||||
"type": "text",
|
|
||||||
"primaryKey": false,
|
|
||||||
"notNull": false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"indexes": {},
|
|
||||||
"foreignKeys": {
|
|
||||||
"sucursales_id_dataset_datasets_id_fk": {
|
|
||||||
"name": "sucursales_id_dataset_datasets_id_fk",
|
|
||||||
"tableFrom": "sucursales",
|
|
||||||
"tableTo": "datasets",
|
|
||||||
"columnsFrom": [
|
|
||||||
"id_dataset"
|
|
||||||
],
|
|
||||||
"columnsTo": [
|
|
||||||
"id"
|
|
||||||
],
|
|
||||||
"onDelete": "no action",
|
|
||||||
"onUpdate": "no action"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"compositePrimaryKeys": {},
|
|
||||||
"uniqueConstraints": {
|
|
||||||
"sucursales_id_dataset_id_comercio_id_bandera_id_sucursal_key": {
|
|
||||||
"name": "sucursales_id_dataset_id_comercio_id_bandera_id_sucursal_key",
|
|
||||||
"nullsNotDistinct": false,
|
|
||||||
"columns": [
|
|
||||||
"id_dataset",
|
|
||||||
"id_comercio",
|
|
||||||
"id_bandera",
|
|
||||||
"id_sucursal"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"enums": {},
|
|
||||||
"schemas": {},
|
|
||||||
"sequences": {},
|
|
||||||
"_meta": {
|
|
||||||
"columns": {},
|
|
||||||
"schemas": {},
|
|
||||||
"tables": {}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -29,13 +29,6 @@
|
||||||
"when": 1726283266814,
|
"when": 1726283266814,
|
||||||
"tag": "0003_strong_bucky",
|
"tag": "0003_strong_bucky",
|
||||||
"breakpoints": true
|
"breakpoints": true
|
||||||
},
|
|
||||||
{
|
|
||||||
"idx": 4,
|
|
||||||
"version": "7",
|
|
||||||
"when": 1726534597731,
|
|
||||||
"tag": "0004_mushy_ultragirl",
|
|
||||||
"breakpoints": true
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -1,10 +1,22 @@
|
||||||
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 { ilike, or, 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')
|
||||||
|
@ -12,12 +24,8 @@ 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 = db
|
const productosQuery = sql`
|
||||||
.select({
|
SELECT id_producto, productos_descripcion, productos_marca,
|
||||||
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
|
||||||
|
@ -29,31 +37,32 @@ 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 = productos_descripcion_index.id_producto)`.as('in_datasets_count')
|
WHERE p.id_producto = index.id_producto) as in_datasets_count
|
||||||
})
|
FROM productos_descripcion_index index
|
||||||
.from(schema.productos_descripcion_index)
|
WHERE productos_descripcion ILIKE ${`%${query}%`}
|
||||||
.where(
|
ORDER BY in_datasets_count desc
|
||||||
or(
|
LIMIT 100
|
||||||
sql`to_tsvector('spanish', ${schema.productos_descripcion_index.productos_descripcion}) @@ to_tsquery('spanish', ${query})`,
|
`;
|
||||||
ilike(schema.productos_descripcion_index.productos_marca, `%${query}%`)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.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.toSQL().sql,
|
name: productosQuery,
|
||||||
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) => BigInt(p.id_producto) === producto.id_producto);
|
const existingProduct = acc.find((p) => 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,
|
||||||
|
@ -61,8 +70,8 @@ WHERE p.id_producto = productos_descripcion_index.id_producto)`.as('in_datasets_
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
acc.push({
|
acc.push({
|
||||||
id_producto: producto.id_producto!.toString(),
|
id_producto: producto.id_producto,
|
||||||
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
|
||||||
});
|
});
|
||||||
|
@ -81,5 +90,63 @@ WHERE p.id_producto = productos_descripcion_index.id_producto)`.as('in_datasets_
|
||||||
'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
|
||||||
|
// };
|
||||||
};
|
};
|
||||||
|
|
|
@ -34,8 +34,9 @@
|
||||||
<h1 class="my-2 text-2xl font-bold">Resultados para "{data.query}"</h1>
|
<h1 class="my-2 text-2xl font-bold">Resultados para "{data.query}"</h1>
|
||||||
{#if data.collapsedProductos.length === 0}
|
{#if data.collapsedProductos.length === 0}
|
||||||
<p class="my-2 text-gray-600">
|
<p class="my-2 text-gray-600">
|
||||||
No se encontraron resultados para "{data.query}". Probá buscando palabras clave como
|
No se encontraron resultados para "{data.query}". Tené en cuenta que actualmente, el algoritmo
|
||||||
"alfajor", "ketchup" o "lenteja".
|
de búsqueda es muy básico. Probá buscando palabras clave como "alfajor", "ketchup" o
|
||||||
|
"lenteja".
|
||||||
</p>
|
</p>
|
||||||
{:else}
|
{:else}
|
||||||
{#each data.collapsedProductos as producto}
|
{#each data.collapsedProductos as producto}
|
||||||
|
|
Loading…
Reference in a new issue