feat: add search queries with partial matching and fuzzy fallback
- Add SearchMediaItems query with ILIKE partial matching - Add SearchMediaItemsFuzzy query with word_similarity() - Use sqlc.narg() for named parameters (search_pattern, search_query) - Rank results by relevance: title > author > series > tags - Fuzzy threshold set to 0.3 for word_similarity - Generated Go models with proper parameter types
This commit is contained in:
@@ -284,6 +284,57 @@ DELETE FROM media_ratings WHERE media_item_id = $1 AND user_id = $2;
|
||||
-- name: GetEbookByFilePath :one
|
||||
SELECT * FROM ebooks WHERE file_path = $1;
|
||||
|
||||
-- Search Media Items queries
|
||||
-- name: SearchMediaItems :many
|
||||
SELECT mi.*, l.name as library_name, lt.name as library_type_name
|
||||
FROM media_items mi
|
||||
JOIN libraries l ON mi.library_id = l.id
|
||||
JOIN library_types lt ON l.library_type_id = lt.id
|
||||
LEFT JOIN library_visibility lv ON l.id = lv.library_id AND lv.user_id = sqlc.narg('user_id')
|
||||
WHERE COALESCE(lv.is_visible, true) = true
|
||||
AND (
|
||||
mi.title ILIKE sqlc.narg('search_pattern') OR
|
||||
mi.author ILIKE sqlc.narg('search_pattern') OR
|
||||
mi.series ILIKE sqlc.narg('search_pattern') OR
|
||||
mi.tags ILIKE sqlc.narg('search_pattern') OR
|
||||
mi.contributors ILIKE sqlc.narg('search_pattern')
|
||||
)
|
||||
ORDER BY
|
||||
CASE
|
||||
WHEN mi.title ILIKE sqlc.narg('search_pattern') THEN 1
|
||||
WHEN mi.author ILIKE sqlc.narg('search_pattern') THEN 2
|
||||
WHEN mi.series ILIKE sqlc.narg('search_pattern') THEN 3
|
||||
WHEN mi.tags ILIKE sqlc.narg('search_pattern') THEN 4
|
||||
ELSE 5
|
||||
END,
|
||||
mi.title ASC
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
|
||||
-- name: SearchMediaItemsFuzzy :many
|
||||
SELECT mi.*, l.name as library_name, lt.name as library_type_name
|
||||
FROM media_items mi
|
||||
JOIN libraries l ON mi.library_id = l.id
|
||||
JOIN library_types lt ON l.library_type_id = lt.id
|
||||
LEFT JOIN library_visibility lv ON l.id = lv.library_id AND lv.user_id = sqlc.narg('user_id')
|
||||
WHERE COALESCE(lv.is_visible, true) = true
|
||||
AND (
|
||||
word_similarity(sqlc.narg('search_query'), mi.title) > 0.3 OR
|
||||
word_similarity(sqlc.narg('search_query'), COALESCE(mi.author, '')) > 0.3 OR
|
||||
word_similarity(sqlc.narg('search_query'), COALESCE(mi.series, '')) > 0.3 OR
|
||||
word_similarity(sqlc.narg('search_query'), COALESCE(mi.tags, '')) > 0.3 OR
|
||||
word_similarity(sqlc.narg('search_query'), COALESCE(mi.contributors, '')) > 0.3
|
||||
)
|
||||
ORDER BY
|
||||
GREATEST(
|
||||
word_similarity(sqlc.narg('search_query'), mi.title),
|
||||
word_similarity(sqlc.narg('search_query'), COALESCE(mi.author, '')),
|
||||
word_similarity(sqlc.narg('search_query'), COALESCE(mi.series, '')),
|
||||
word_similarity(sqlc.narg('search_query'), COALESCE(mi.tags, '')),
|
||||
word_similarity(sqlc.narg('search_query'), COALESCE(mi.contributors, ''))
|
||||
) DESC,
|
||||
mi.title ASC
|
||||
LIMIT sqlc.narg('limit') OFFSET sqlc.narg('offset');
|
||||
|
||||
-- Media Notes queries
|
||||
-- name: CreateMediaNote :one
|
||||
INSERT INTO media_notes (media_item_id, user_id, content, position)
|
||||
|
||||
Reference in New Issue
Block a user