Files
music_library/lib/music_library/search.ex
T
2026-03-12 16:21:04 +00:00

98 lines
2.9 KiB
Elixir

defmodule MusicLibrary.Search do
@moduledoc """
Universal search functionality across Records and Artists.
This module provides unified search across:
- Records in Collection (purchased records)
- Records in Wishlist (unpurchased records)
- Artists
"""
alias MusicLibrary.{Artists, Collection, RecordSets, Wishlist}
@pagination Application.compile_env!(:music_library, :pagination)
@type search_opts :: [limit: non_neg_integer()]
@doc """
Performs a universal search across all entity types.
Returns a map with grouped results:
- :collection - Records in the collection
- :wishlist - Records in the wishlist
- :artists - Artists
"""
@spec universal_search(String.t(), search_opts()) :: map()
def universal_search(query, opts \\ []) do
limit = Keyword.get(opts, :limit, @pagination[:search_preview_limit])
%{
collection: search_collection(query, limit),
wishlist: search_wishlist(query, limit),
artists: search_artists(query, limit),
record_sets: search_record_sets(query, limit)
}
end
@doc """
Searches records in the collection (purchased records).
"""
@spec search_collection(String.t(), non_neg_integer()) :: [map()]
def search_collection(query, limit \\ @pagination[:search_preview_limit]) do
Collection.search_records(query, limit: limit)
end
@doc """
Searches records in the wishlist (unpurchased records).
"""
@spec search_wishlist(String.t(), non_neg_integer()) :: [map()]
def search_wishlist(query, limit \\ @pagination[:search_preview_limit]) do
Wishlist.search_records(query, limit: limit)
end
@doc """
Searches artists by name.
Searches across artist names in the artist_records table,
returning distinct artists that match the query.
"""
@spec search_artists(String.t(), non_neg_integer()) :: [map()]
def search_artists(query, limit \\ @pagination[:search_preview_limit]) do
Artists.search_by_name(query, limit)
end
@doc """
Gets the count of search results for each category.
Returns a map with counts for each category:
- :collection_count
- :wishlist_count
- :artists_count
"""
@spec search_counts(String.t()) :: map()
def search_counts(query) do
%{
collection_count: Collection.search_records_count(query),
wishlist_count: Wishlist.search_records_count(query),
artists_count: search_artists_count(query),
record_sets_count: RecordSets.count_record_sets(query)
}
end
@doc """
Searches record sets by name, description, and contained records.
"""
@spec search_record_sets(String.t(), non_neg_integer()) :: [map()]
def search_record_sets(query, limit \\ @pagination[:search_preview_limit]) do
RecordSets.search_record_sets(query, limit: limit)
end
@doc """
Gets the count of artists matching the search query.
"""
@spec search_artists_count(String.t()) :: non_neg_integer()
def search_artists_count(query) do
Artists.search_by_name_count(query)
end
end