51 lines
1.5 KiB
Python
51 lines
1.5 KiB
Python
|
|
"""Autocomplete / Suggest endpoint (Typ 11)."""
|
||
|
|
from app import db
|
||
|
|
from app.schemas import SuggestItem
|
||
|
|
|
||
|
|
|
||
|
|
async def top_brands(limit: int = 10) -> list[SuggestItem]:
|
||
|
|
rows = await db.fetch(
|
||
|
|
"SELECT brand, count(*) AS cnt FROM search_vehicles "
|
||
|
|
"WHERE brand IS NOT NULL GROUP BY brand ORDER BY cnt DESC LIMIT $1",
|
||
|
|
limit,
|
||
|
|
)
|
||
|
|
return [
|
||
|
|
SuggestItem(text=r["brand"], type="brand", count=r["cnt"])
|
||
|
|
for r in rows
|
||
|
|
]
|
||
|
|
|
||
|
|
|
||
|
|
async def prefix_suggest(prefix: str, limit: int = 8) -> list[SuggestItem]:
|
||
|
|
"""Brand + model prefix matching, case-insensitive."""
|
||
|
|
pattern = f"{prefix.lower()}%"
|
||
|
|
|
||
|
|
# Brands first
|
||
|
|
brand_rows = await db.fetch(
|
||
|
|
"SELECT brand, count(*) AS cnt FROM search_vehicles "
|
||
|
|
"WHERE LOWER(brand) LIKE $1 GROUP BY brand ORDER BY cnt DESC LIMIT $2",
|
||
|
|
pattern,
|
||
|
|
limit,
|
||
|
|
)
|
||
|
|
items = [
|
||
|
|
SuggestItem(text=r["brand"], type="brand", count=r["cnt"])
|
||
|
|
for r in brand_rows
|
||
|
|
]
|
||
|
|
|
||
|
|
# Then models if room
|
||
|
|
remaining = limit - len(items)
|
||
|
|
if remaining > 0:
|
||
|
|
model_rows = await db.fetch(
|
||
|
|
"SELECT DISTINCT brand || ' ' || model AS text, count(*) AS cnt "
|
||
|
|
"FROM search_vehicles "
|
||
|
|
"WHERE model IS NOT NULL AND LOWER(model) LIKE $1 "
|
||
|
|
"GROUP BY brand, model ORDER BY cnt DESC LIMIT $2",
|
||
|
|
pattern,
|
||
|
|
remaining,
|
||
|
|
)
|
||
|
|
items.extend(
|
||
|
|
SuggestItem(text=r["text"], type="model", count=r["cnt"])
|
||
|
|
for r in model_rows
|
||
|
|
)
|
||
|
|
|
||
|
|
return items
|