Search Overhaul - Phase 1 - #26
Merged
Merged
Conversation
Trove and Collection searchable arrays gain tag_ids, trove_type_ids, locales and a shared sort_date attribute; collections aggregate tags and types from published canonical members only. Filterable, sortable and searchable attributes are declared in config/scout.php so scout:sync-index-settings versions them.
…tions MeilisearchLibrarySearch issues one federated multi-search request (shared filter expressions, sort_date ordering for blank queries, federation-level pagination and merged facets). DatabaseLibrarySearch is the portable-SQL fallback for null-driver installs and outages. The container binds the contract by scout driver. UsesCustomSearchOptions is still referenced by the old BrowseAll and will be deleted with its rewrite.
BrowseAll is now a single full-page component holding only scalar query/filter/page state (all in the URL), issuing one SearchesLibrary request per render and hydrating one page of models in hit order. An engine outage flags a notice and re-runs through the database fallback. Filter tag types are fetched and sorted in PHP (the MySQL-only ISNULL/JSON_EXTRACT ordering is gone), so the whole render path now runs on SQLite. SearchBar and UsesCustomSearchOptions are deleted; the search input lives inline in the blade.
…, alt text The sidebar gains a resource-type filter group; every tag/type/language checkbox shows a facet count badge (zero-count options muted and disabled unless already selected; no badges in fallback mode). Pagination is windowed First/Prev/window/Next/Last buttons with aria-current and real disabled attributes, replacing the Alpine entangle machinery. Card images get alt text / aria-labels.
…cies Tags and member-trove data are denormalised into the index, so changes outside the trove-save path now reindex the affected documents: a TagObserver reindexes a renamed/deleted tag's published troves and their collections (member ids captured at deleting, before the pivot cascade); the AllTrovesTable attach/detach/bulk-attach actions and the TrovesRelationManager detach actions reindex the collection; and TrovePublisher reindexes affected collections after publish (both sides of a membership change), unpublish and delete, deferred to after commit. Also inlines the publisher's single-use NON_CONTENT constant.
The hardcoded themes/topics slugs were a Stats4SD leftover; the only consumer was the old BrowseAll (whose cards hide tags anyway). Sweep for dangling references came back clean; full suite green.
- integration tests for meilisearch engine - documentation - update facet counts so they don't count their own tag type filters
Updated PHP version and health check parameters in CI workflow.
…tead of dropping unit
Member
Author
|
@ciara-mc - debugged and fixed the issues with the CI test runner:
All tests now passing here on GitHub, just like locally 👍 |
Contributor
ciara-mc
reviewed
Jul 20, 2026
ciara-mc
left a comment
Contributor
There was a problem hiding this comment.
After upgrading my meilisearch - this works well
Member
Author
Agreed; I've updated the text to say:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

High-level overview: Full rewrite of the BrowseAll page, search / tag filtering. Now all searching + filtering happens on Meilisearch, rather than searching on Meilisearch and filtering via Eloquent queries.
Thoughts on the Search Engine / Meilisearch
I thought about whether or not to pull back from Meilisearch and go with a more "generic" tool that people can use with their own search engine choices, but honestly Meilisearch is one of the only robust tools like this that is fully open source and self-hostable. ElasticSearch is another potential option, but requires a huge amount more setup / learning, and is somewhat overkill here. So instead this work leans into Meilisearch, and makes the 'search' feature explicitly dependent on it.
Implementation Details
config/scout.phpso that Trove and Collection indexes can be sorted and filtered as well as searched.toSearchableArray()methods to include the tags and trove types needed to make filtering work.Services\Search\and the BrowseAll page uses an interface. This means we can have 2 versions of the search service (one Meilisearch, and one Database only, for if Meilisearch is ever unreachable) - so if Meilisearch goes offline, the user will still be able to browse and filter (just not do a keyword search, though we can potentially add that back by using MySQL full-text search in the DatabaseLibrarySearch class...)SearchesLibrary::class,'new' Features: