️ /stop API endpoint uses stop and towns names to resolve queries

This commit is contained in:
2023-05-01 22:42:02 +02:00
parent bcedf32bec
commit 6eb78d7307

View File

@@ -5,9 +5,12 @@ from typing import Iterable, Sequence, TYPE_CHECKING
from sqlalchemy import (
BigInteger,
Column,
Computed,
desc,
Enum,
Float,
ForeignKey,
func,
Integer,
JSON,
select,
@@ -22,6 +25,7 @@ from sqlalchemy.orm import (
with_polymorphic,
)
from sqlalchemy.schema import Index
from sqlalchemy_utils.types.ts_vector import TSVectorType
from ..db import Base, db
from ..idfm_interface.idfm_types import TransportMode, IdfmState, StopAreaType
@@ -71,13 +75,17 @@ class _Stop(Base):
back_populates="stops", lazy="selectin"
)
names_tsv = mapped_column(
TSVectorType("name", "town_name", regconfig="french"),
Computed("to_tsvector('french', name || ' ' || town_name)", persisted=True),
)
__tablename__ = "_stops"
__mapper_args__ = {"polymorphic_identity": "_stops", "polymorphic_on": kind}
__table_args__ = (
# To optimize the ilike requests
Index(
"name_idx_gin",
name,
"names_tsv_idx",
names_tsv,
postgresql_ops={"name": "gin_trgm_ops"},
postgresql_using="gin",
),
@@ -92,9 +100,15 @@ class _Stop(Base):
return None
stop_stop_area = with_polymorphic(_Stop, [Stop, StopArea])
match_stmt = stop_stop_area.names_tsv.match(name, postgresql_regconfig="french")
ranking_stmt = func.ts_rank_cd(
stop_stop_area.names_tsv, func.plainto_tsquery("french", name)
)
stmt = (
select(stop_stop_area)
.where(stop_stop_area.name.ilike(f"%{name}%"))
.filter(match_stmt)
.order_by(desc(ranking_stmt))
.options(
selectinload(stop_stop_area.areas),
selectinload(stop_stop_area.lines),