Spaces:
Sleeping
Sleeping
File size: 9,614 Bytes
fddb26d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 | CREATE OR REPLACE FUNCTION match_pois_hybrid(
query_embedding vector(384),
match_threshold float DEFAULT 0.5,
match_count int DEFAULT 200,
alpha_weight float DEFAULT 0.7,
beta_weight float DEFAULT 0.3,
p_city text DEFAULT NULL,
p_neighborhood text DEFAULT NULL,
p_main_category text DEFAULT NULL,
p_sub_category text DEFAULT NULL,
p_cuisine text DEFAULT NULL,
p_min_rating float DEFAULT NULL,
p_rank int DEFAULT NULL,
p_tags text[] DEFAULT ARRAY[]::text[],
p_avoid text[] DEFAULT ARRAY[]::text[],
p_open_now boolean DEFAULT NULL,
p_is_24_7 boolean DEFAULT NULL,
p_route_enabled boolean DEFAULT false,
p_route_origin text DEFAULT NULL,
p_route_stops text[] DEFAULT ARRAY[]::text[],
p_route_destination text DEFAULT NULL,
p_user_lat float DEFAULT NULL,
p_user_lng float DEFAULT NULL,
p_proximity_enabled boolean DEFAULT false,
p_max_distance_km float DEFAULT NULL,
p_is_restaurant_query boolean DEFAULT false,
p_is_istanbul_route boolean DEFAULT false,
p_use_route_stops boolean DEFAULT false,
p_destination_priority boolean DEFAULT false
)
RETURNS TABLE (
id uuid,
display_title text,
city text,
neighborhood text,
main_category text,
sub_category text,
cuisine text,
total_score float,
rank int,
tags text[],
latitude float,
longitude float,
is_24_7 boolean,
semantic_similarity float,
metadata_score float,
candidate_score float
)
LANGUAGE sql
AS $$
WITH base AS (
SELECT
p.id,
p.display_title,
p.city,
p.neighborhood,
p.main_category,
p.sub_category,
r.cuisine_type AS cuisine,
p.total_score,
p.rank,
p.tags,
p.latitude,
p.longitude,
p.is_24_7,
p.embedding,
1 - (p.embedding <=> query_embedding) AS semantic_similarity,
(
CASE WHEN p_min_rating IS NOT NULL AND p.total_score >= p_min_rating THEN 1 ELSE 0 END +
CASE WHEN p_rank IS NOT NULL AND p.rank <= p_rank THEN 1 ELSE 0 END +
CASE WHEN array_length(p_tags, 1) IS NOT NULL AND p.tags @> p_tags THEN 1 ELSE 0 END +
CASE WHEN p_open_now IS TRUE THEN 1 ELSE 0 END +
CASE WHEN p_is_24_7 IS TRUE AND p.is_24_7 IS TRUE THEN 1 ELSE 0 END
)::float / 5.0 AS metadata_score
FROM places p
LEFT JOIN restaurants r
ON r.place_id = p.id
AND (
p_is_restaurant_query IS TRUE
OR p_main_category = 'Restaurant'
OR p_cuisine IS NOT NULL
)
LEFT JOIN restaurant_dishes rd
ON rd.restaurant_id = r.id
AND p_cuisine IS NOT NULL
AND rd.display_title ILIKE '%' || p_cuisine || '%'
WHERE
-- permanently closed filtre
COALESCE(p.permanently_closed, false) = false
-- semantic threshold
AND (1 - (p.embedding <=> query_embedding)) >= match_threshold
-- category filtreleri
AND (p_main_category IS NULL OR p.main_category = p_main_category)
AND (p_sub_category IS NULL OR p.sub_category = p_sub_category)
AND (
p_cuisine IS NULL
OR r.cuisine_type = p_cuisine
OR rd.display_title ILIKE '%' || p_cuisine || '%'
)
-- location filtreleri
AND (
p_is_istanbul_route IS TRUE
OR p_city IS NULL
OR p.city = p_city
)
AND (
p_is_istanbul_route IS TRUE
OR p_neighborhood IS NULL
OR p.neighborhood = p_neighborhood
)
-- route stops aggregation
AND (
p_use_route_stops IS FALSE
OR p.city = ANY(p_route_stops)
OR p.neighborhood = ANY(p_route_stops)
)
-- destination priority
AND (
p_destination_priority IS FALSE
OR p.city = p_route_destination
OR p.neighborhood = p_route_destination
)
-- total_score / rank
AND (p_min_rating IS NULL OR p.total_score >= p_min_rating)
AND (p_rank IS NULL OR p.rank <= p_rank)
-- tags contains
AND (
array_length(p_tags, 1) IS NULL
OR p.tags @> p_tags
)
-- avoid negative filter
AND (
array_length(p_avoid, 1) IS NULL
OR NOT (p.tags && p_avoid)
)
-- 24/7
AND (
p_is_24_7 IS NULL
OR p.is_24_7 = p_is_24_7
)
-- proximity null-safe
AND (
p_proximity_enabled IS FALSE
OR p_user_lat IS NULL
OR p_user_lng IS NULL
OR p_max_distance_km IS NULL
OR (
6371 * acos(
cos(radians(p_user_lat))
* cos(radians(p.latitude))
* cos(radians(p.longitude) - radians(p_user_lng))
+ sin(radians(p_user_lat))
* sin(radians(p.latitude))
)
) <= p_max_distance_km
)
)
SELECT
base.id,
base.display_title,
base.city,
base.neighborhood,
base.main_category,
base.sub_category,
base.cuisine,
base.total_score,
base.rank,
base.tags,
base.latitude,
base.longitude,
base.is_24_7,
base.semantic_similarity,
base.metadata_score,
(
alpha_weight * base.semantic_similarity
+ beta_weight * base.metadata_score
) AS candidate_score
FROM base
ORDER BY candidate_score DESC
LIMIT match_count;
$$;
CREATE OR REPLACE FUNCTION match_pois_metadata_only(
match_count int DEFAULT 200,
p_city text DEFAULT NULL,
p_neighborhood text DEFAULT NULL,
p_main_category text DEFAULT NULL,
p_sub_category text DEFAULT NULL,
p_cuisine text DEFAULT NULL,
p_min_rating float DEFAULT NULL,
p_rank int DEFAULT NULL,
p_tags text[] DEFAULT ARRAY[]::text[],
p_avoid text[] DEFAULT ARRAY[]::text[],
p_open_now boolean DEFAULT NULL,
p_is_24_7 boolean DEFAULT NULL,
p_route_enabled boolean DEFAULT false,
p_route_origin text DEFAULT NULL,
p_route_stops text[] DEFAULT ARRAY[]::text[],
p_route_destination text DEFAULT NULL,
p_user_lat float DEFAULT NULL,
p_user_lng float DEFAULT NULL,
p_proximity_enabled boolean DEFAULT false,
p_max_distance_km float DEFAULT NULL,
p_is_restaurant_query boolean DEFAULT false,
p_is_istanbul_route boolean DEFAULT false,
p_use_route_stops boolean DEFAULT false,
p_destination_priority boolean DEFAULT false
)
RETURNS TABLE (
id uuid,
display_title text,
city text,
neighborhood text,
main_category text,
sub_category text,
cuisine text,
total_score float,
rank int,
tags text[],
latitude float,
longitude float,
is_24_7 boolean,
metadata_score float,
candidate_score float
)
LANGUAGE sql
AS $$
SELECT
p.id,
p.display_title,
p.city,
p.neighborhood,
p.main_category,
p.sub_category,
r.cuisine_type AS cuisine,
p.total_score,
p.rank,
p.tags,
p.latitude,
p.longitude,
p.is_24_7,
(
CASE WHEN p_min_rating IS NOT NULL AND p.total_score >= p_min_rating THEN 1 ELSE 0 END +
CASE WHEN p_rank IS NOT NULL AND p.rank <= p_rank THEN 1 ELSE 0 END +
CASE WHEN array_length(p_tags, 1) IS NOT NULL AND p.tags @> p_tags THEN 1 ELSE 0 END +
CASE WHEN p_is_24_7 IS TRUE AND p.is_24_7 IS TRUE THEN 1 ELSE 0 END
)::float / 4.0 AS metadata_score,
(
CASE WHEN p_min_rating IS NOT NULL AND p.total_score >= p_min_rating THEN 1 ELSE 0 END +
CASE WHEN p_rank IS NOT NULL AND p.rank <= p_rank THEN 1 ELSE 0 END +
CASE WHEN array_length(p_tags, 1) IS NOT NULL AND p.tags @> p_tags THEN 1 ELSE 0 END +
CASE WHEN p_is_24_7 IS TRUE AND p.is_24_7 IS TRUE THEN 1 ELSE 0 END
)::float / 4.0 AS candidate_score
FROM places p
LEFT JOIN restaurants r
ON r.place_id = p.id
AND (
p_is_restaurant_query IS TRUE
OR p_main_category = 'Restaurant'
OR p_cuisine IS NOT NULL
)
LEFT JOIN restaurant_dishes rd
ON rd.restaurant_id = r.id
AND p_cuisine IS NOT NULL
AND rd.display_title ILIKE '%' || p_cuisine || '%'
WHERE
COALESCE(p.permanently_closed, false) = false
AND (p_main_category IS NULL OR p.main_category = p_main_category)
AND (p_sub_category IS NULL OR p.sub_category = p_sub_category)
AND (
p_cuisine IS NULL
OR r.cuisine_type = p_cuisine
OR rd.display_title ILIKE '%' || p_cuisine || '%'
)
AND (
p_is_istanbul_route IS TRUE
OR p_city IS NULL
OR p.city = p_city
)
AND (
p_is_istanbul_route IS TRUE
OR p_neighborhood IS NULL
OR p.neighborhood = p_neighborhood
)
AND (
p_use_route_stops IS FALSE
OR p.city = ANY(p_route_stops)
OR p.neighborhood = ANY(p_route_stops)
)
AND (
p_destination_priority IS FALSE
OR p.city = p_route_destination
OR p.neighborhood = p_route_destination
)
AND (p_min_rating IS NULL OR p.total_score >= p_min_rating)
AND (p_rank IS NULL OR p.rank <= p_rank)
AND (
array_length(p_tags, 1) IS NULL
OR p.tags @> p_tags
)
AND (
array_length(p_avoid, 1) IS NULL
OR NOT (p.tags && p_avoid)
)
AND (
p_is_24_7 IS NULL
OR p.is_24_7 = p_is_24_7
)
ORDER BY candidate_score DESC
LIMIT match_count;
$$; |