diff --git a/API.md b/API.md index 915b319..180f3ab 100644 --- a/API.md +++ b/API.md @@ -120,6 +120,28 @@ __Notes :__ --------------------- +### /api/map/search_place?text=TEXT +> Return a list of dict representing all names (place name or user name) +> which matches the query TEXT, along with associated place id. + +__Format of the dict :__ +```json +[ + { + 'type': char, //'U' if matching text is an user name, 'P' if it is a place name + 'txt':string, //the matching name (whichever type) + 'pid': int, //id of the associated place + 'floor' : string, //id of the lowest floor the place is part of + 'rank': float //the «match» score of this txt against query TEXT + }, + {...} +] +``` +__Notes :__ +- If _NAME_ doesn't correspond to any registered place : Return an Empty list. + +--------------------- + ### /api/map/get_site_name/ID > Return the name of the Site ID. diff --git a/src/Controller/MapApiController.php b/src/Controller/MapApiController.php index f12e68d..389b56f 100644 --- a/src/Controller/MapApiController.php +++ b/src/Controller/MapApiController.php @@ -8,6 +8,7 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\UnprocessableEntityHttpException; use Symfony\Component\HttpKernel\Exception\HttpException; use Symfony\Component\HttpKernel\Exception\PreconditionFailedHttpException; +use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; @@ -158,6 +159,15 @@ class MapApiController extends AbstractController } return $this->json($result); } + + #[Route('/map/search_place')] + public function search_place(Request $request, PlaceRepository $pnRepo) { + $text = $request->query->get('text'); + + $res = $pnRepo->searchPlaceNameAndUser($text); + + return $this->json($res); + } #[Route('/map/get_place_info/{id}')] diff --git a/src/Repository/PlaceRepository.php b/src/Repository/PlaceRepository.php index 7fcfdbb..ac08cff 100644 --- a/src/Repository/PlaceRepository.php +++ b/src/Repository/PlaceRepository.php @@ -77,6 +77,48 @@ class PlaceRepository extends ServiceEntityRepository { return $this->createQueryBuilder('s')->orderBy('s.id','ASC')->getQuery()->getResult(); } + + public function searchPlaceNameAndUser(string $text) + { + $sql = " + ( + SELECT + 'U' AS type, + user_name AS txt, + run.place_id AS pid, + MIN(pf.floor_id) AS floor, + SIMILARITY(user_name,:searchtext) AS rank + FROM room_user_name AS run + JOIN place_floor AS pf ON pf.place_id=run.place_id + GROUP BY run.id + ORDER BY rank DESC + LIMIT :limit + ) + UNION + ( + SELECT + 'P' AS type, + name AS txt, + pn.place_id AS pid, + MIN(pf.floor_id) AS floor, + SIMILARITY(name,:searchtext) AS rank + FROM place_name pn + JOIN place_floor AS pf ON pf.place_id=pn.place_id + GROUP BY pn.id + ORDER BY rank DESC + LIMIT :limit + ) + ORDER BY rank DESC + LIMIT :limit; + "; + + $stmt = $this->getEntityManager()->getConnection()->prepare($sql); + $stmt->bindValue("searchtext",$text); + $stmt->bindValue("limit",5); + $res = $stmt->executeQuery() ; + $out = $res->fetchAllAssociative(); + return $out; + } // public function findOneBySomeField($value): ?Place