mirror of
https://github.com/rommapp/romm.git
synced 2026-07-01 08:16:21 +00:00
fix(search): full-text indexes+caching
Adds a few new indexes to handle full-text searches instead of doing `ILIKE` matching, improving performance substantially. Alongside that, a few other things were done in order to improve search performance, such as caching filter values so they're not computed on each request to /api/roms. Overall, this should have a very noticeable impact on large collections when using the search feature.
This commit is contained in:
@@ -219,6 +219,55 @@ def test_filter_by_search_term_with_multiple_terms(platform: Platform):
|
||||
assert actual_rom_ids_single == expected_rom_ids_single
|
||||
|
||||
|
||||
def test_filter_by_search_term_multi_word_and_ranking(platform: Platform):
|
||||
def _add(name: str) -> Rom:
|
||||
fs = name.replace(" ", "_")
|
||||
return db_rom_handler.add_rom(
|
||||
Rom(
|
||||
platform_id=platform.id,
|
||||
name=name,
|
||||
slug=name.lower().replace(" ", "-"),
|
||||
fs_name=f"{fs}.zip",
|
||||
fs_name_no_tags=fs,
|
||||
fs_name_no_ext=fs,
|
||||
fs_extension="zip",
|
||||
fs_path=f"{platform.slug}/roms",
|
||||
)
|
||||
)
|
||||
|
||||
ff = _add("Final Fantasy")
|
||||
ff7 = _add("Final Fantasy VII")
|
||||
fantasy_final = _add("Fantasy Final") # both words, reversed order
|
||||
_add("Final Combat") # only "final"
|
||||
_add("Angelique - Voice Fantasy") # only "fantasy"
|
||||
_add("Super Mario World") # neither word
|
||||
|
||||
results = db_rom_handler.get_roms_scalar(search_term="final fantasy")
|
||||
result_ids = [r.id for r in results]
|
||||
|
||||
# Only titles containing BOTH words appear (AND semantics).
|
||||
assert set(result_ids) == {ff.id, ff7.id, fantasy_final.id}
|
||||
|
||||
# Exact-order phrase matches rank above the reversed-order match.
|
||||
assert result_ids.index(ff.id) < result_ids.index(fantasy_final.id)
|
||||
assert result_ids.index(ff7.id) < result_ids.index(fantasy_final.id)
|
||||
|
||||
# The relevance ORDER BY must also survive the group_by_meta_id subquery
|
||||
# wrapping used by the gallery (each ROM here is its own group).
|
||||
grouped = db_rom_handler.get_roms_scalar(
|
||||
search_term="final fantasy", group_by_meta_id=True
|
||||
)
|
||||
assert {r.id for r in grouped} == {ff.id, ff7.id, fantasy_final.id}
|
||||
|
||||
# An explicit sort takes priority over relevance: ordering by name asc puts
|
||||
# "Fantasy Final" first (relevance is only the tiebreaker here).
|
||||
explicit = db_rom_handler.get_roms_scalar(
|
||||
search_term="final fantasy", order_by="name", order_dir="asc"
|
||||
)
|
||||
explicit_ids = [r.id for r in explicit]
|
||||
assert explicit_ids.index(fantasy_final.id) < explicit_ids.index(ff.id)
|
||||
|
||||
|
||||
def test_sibling_roms_empty_fs_name_no_tags_not_matched(platform: Platform):
|
||||
"""ROMs with empty fs_name_no_tags should NOT be matched as siblings.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user