mirror of
https://github.com/catdevnull/preciazo.git
synced 2024-11-22 06:16:18 +00:00
search
This commit is contained in:
parent
a3bdc59b73
commit
76db90618c
2 changed files with 68 additions and 19 deletions
|
@ -213,6 +213,51 @@ order by fetched_at
|
|||
|
||||
Json(precios)
|
||||
}
|
||||
async fn search(State(pool): State<SqlitePool>, Path(query): Path<String>) -> impl IntoResponse {
|
||||
let sql_query = query
|
||||
.clone()
|
||||
.replace("\"", "\"\"")
|
||||
.split(" ")
|
||||
.map(|x| format!("\"{}\"", x))
|
||||
.join(" ");
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct Result {
|
||||
ean: String,
|
||||
name: String,
|
||||
image_url: String,
|
||||
}
|
||||
|
||||
let results = sqlx::query!(
|
||||
"with search_results as (
|
||||
select f.ean from precios_fts f
|
||||
where f.name match ? and f.ean != ''
|
||||
group by f.ean
|
||||
limit 100
|
||||
)
|
||||
select p.id, p.ean, p.name, p.image_url from search_results as s
|
||||
join precios as p
|
||||
on p.ean = s.ean
|
||||
where p.fetched_at = (
|
||||
SELECT MAX(fetched_at)
|
||||
FROM precios as pf
|
||||
WHERE pf.ean = s.ean and pf.name is not null
|
||||
);",
|
||||
sql_query
|
||||
)
|
||||
.fetch_all(&pool)
|
||||
.await
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|r| Result {
|
||||
ean: r.ean,
|
||||
image_url: r.image_url.unwrap(),
|
||||
name: r.name.unwrap(),
|
||||
})
|
||||
.collect_vec();
|
||||
|
||||
Json(results)
|
||||
}
|
||||
|
||||
async fn get_info(State(pool): State<SqlitePool>) -> impl IntoResponse {
|
||||
#[derive(Serialize)]
|
||||
|
@ -267,6 +312,7 @@ async fn main() {
|
|||
.route("/api/0/best-selling-products", get(get_best_selling))
|
||||
.route("/api/0/ean/:ean/history", get(get_product_history))
|
||||
.route("/api/0/info", get(get_info))
|
||||
.route("/api/0/search/:query", get(search))
|
||||
.with_state(pool);
|
||||
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:8000").await.unwrap();
|
||||
|
|
|
@ -1,26 +1,29 @@
|
|||
import { sql } from "drizzle-orm";
|
||||
import { z } from "zod";
|
||||
import type { PageServerLoad } from "./$types";
|
||||
import { getDb } from "$lib/server/db";
|
||||
import { API_HOST } from "$lib";
|
||||
import ky from "ky";
|
||||
|
||||
const zProductResult = z.object({
|
||||
ean: z.string(),
|
||||
name: z.string(),
|
||||
image_url: z.string(),
|
||||
});
|
||||
|
||||
async function search(query: string) {
|
||||
return z
|
||||
.array(zProductResult)
|
||||
.parse(
|
||||
await ky
|
||||
.get(`${API_HOST}/api/0/search/${encodeURIComponent(query)}`)
|
||||
.json(),
|
||||
);
|
||||
}
|
||||
|
||||
export const load: PageServerLoad = async ({ url }) => {
|
||||
const db = await getDb();
|
||||
const query = url.searchParams.get("q");
|
||||
let results: null | { ean: string; name: string; imageUrl: string }[] = null;
|
||||
if (query) {
|
||||
const sQuery = query
|
||||
.replaceAll(`"`, `""`)
|
||||
.split(" ")
|
||||
.map((s) => `"${s}"`)
|
||||
.join(" ");
|
||||
console.debug(sQuery);
|
||||
const sqlQuery = sql`select p.ean, p.name, p.image_url as imageUrl from precios_fts f
|
||||
join precios p on p.ean = f.ean
|
||||
where f.name match ${sQuery}
|
||||
group by p.ean
|
||||
having max(p.fetched_at)
|
||||
order by p.in_stock desc;`;
|
||||
results = db.all(sqlQuery);
|
||||
}
|
||||
let results: null | { ean: string; name: string; image_url: string }[] = query
|
||||
? await search(query)
|
||||
: null;
|
||||
|
||||
return { query, results };
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue