11 | | 2. Корисникот има можност да ги филтрира резултатите според горенаведените преференци. |
| 11 | 2. Системот потоа: |
| 12 | * Ја користи табелата destination како главен извор на податоци. |
| 13 | * Преку LEFT JOIN се приклучуваат destination_tag и tag за филтрирање и прикажување на категории/ознаки. |
| 14 | * Преку LEFT JOIN кон review и destination_user се добиваат информации за просечен рејтинг и коментари. |
| 15 | * Условите се применуваат само ако корисникот внел вредности (инаку се игнорираат). |
| 16 | * ILIKE за case-insensitive пребарување. |
| 17 | * Популарноста се проверува врз основа на полето popularity од табелата destination. |
| 18 | Резултатот е листа на дестинации со основни информации, просечен рејтинг и поврзани ознаки. |
13 | | SELECT DISTINCT d.* |
14 | | FROM DESTINACII d |
15 | | LEFT JOIN RECENZII r ON d.idDest = r.idDest |
| 20 | SELECT d.id_destination, |
| 21 | d.location_name, |
| 22 | d.location_desc, |
| 23 | d.types_of_places, |
| 24 | d.recommended_season, |
| 25 | d.country, |
| 26 | d.popularity, |
| 27 | ARRAY_AGG(DISTINCT t.tag_name) AS tags, |
| 28 | COALESCE(ROUND(AVG(r.quality), 2), 0) AS avg_review |
| 29 | FROM travel_sage.destination d |
| 30 | LEFT JOIN travel_sage.destination_tag dt ON d.id_destination = dt.id_destination |
| 31 | LEFT JOIN travel_sage.tag t ON dt.id_tag = t.id_tag |
| 32 | LEFT JOIN travel_sage.review r ON d.id_destination = r.id_destination |
28 | | DESTINACII е главната табела од која се земаат податоци. Преку LEFT JOIN се приклучува табелата RECENZII, со што се овозможува филтрирање и по податоци од рецензии (ако има потреба во иднина). ILIKE овозможува case-insensitive пребарување (на пр. ќе најде и "море" и "Море"). Ако не е внесен некој параметар (NULL), тој услов се игнорира и не се филтрира според него. За популарност, бараме idTag од TAGOVI каде што tagOznaka се наоѓа во дадениот опсег. |
29 | | |
30 | | |
31 | | Ги зема сите дестинации (DESTINACII d). Им се приклучува табелата со рецензии (RECENZII r). Се филтрира според внесените параметри: |
32 | | * тип на место |
33 | | |
34 | | * сезона |
35 | | |
36 | | * популарност |
37 | | |
38 | | |
39 | | {{{ |
40 | | public function index(Request $request) |
41 | | { |
42 | | $tip = $request->input('tipovimesta'); |
43 | | $sezona = $request->input('preporachanasezona'); |
44 | | $popularnost = $request->input('popularnost'); |
45 | | |
46 | | $prioritet_min = null; |
47 | | $prioritet_max = null; |
48 | | |
49 | | if ($popularnost && str_contains($popularnost, '-')) { |
50 | | [$prioritet_min, $prioritet_max] = explode('-', $popularnost); |
51 | | } |
52 | | |
53 | | $sql = " |
54 | | SELECT DISTINCT d.* |
55 | | FROM DESTINACII d |
56 | | LEFT JOIN RECENZII r ON d.idDest = r.idDest |
57 | | WHERE |
58 | | (:tip IS NULL OR d.tipoviMesta ILIKE CONCAT('%', :tip, '%')) |
59 | | AND (:sezona IS NULL OR d.preporachanaSezona ILIKE CONCAT('%', :sezona, '%')) |
60 | | AND ( |
61 | | :prioritet_min IS NULL OR :prioritet_max IS NULL OR |
62 | | d.idTag IN ( |
63 | | SELECT idTag |
64 | | FROM TAGOVI |
65 | | WHERE tagOznaka::int BETWEEN :prioritet_min AND :prioritet_max |
66 | | ) |
67 | | ) |
68 | | "; |
69 | | |
70 | | $destinacii = DB::select($sql, [ |
71 | | 'tip' => $tip !== 'any' ? $tip : null, |
72 | | 'sezona' => $sezona !== 'any' ? $sezona : null, |
73 | | 'prioritet_min' => $prioritet_min, |
74 | | 'prioritet_max' => $prioritet_max, |
75 | | ]); |
76 | | |
77 | | return view('destinations.index', compact('destinacii')); |
78 | | } |
79 | | |
80 | | }}} |