filagora / filagora-search
Engine-agnostic search for Filagora: a SearchEngine contract, Meilisearch and database engines, indexing and health commands.
Requires
- php: ^8.4
- filagora/filagora-core: ^0.2.1
- filament/filament: ^5.0
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.0
- orchestra/testbench: ^11.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-16 00:27:32 UTC
README
Search for Filagora that does not tie you to one engine. It defines a SearchEngine contract and
a portable filter tree, ships a Meilisearch engine and a database fallback, and keeps the index
fresh and healthy with commands. Requires filagora/filagora-core.
The package is at
0.1: the API may change between0.xminor versions. There is no frontend: you build the search pages.
How it fits together
- A package (or your app) registers a
SearchIndex: one kind of thing, how a model becomes aDocument, and afallback()that answers the same query from the database. - You search through
Search:app(Search::class)->search('threads', new SearchQuery('paypal', $filter)). It returns ids; you load the rows and drop anything the index describes wrongly (an index is only as fresh as its last sync). - The engine is
filagora-search.engine:database(the default; no server),array(tests), or one you add withSearchEngines::extend(). If the engine throws, searches are answered from the database forcircuit.cooldown_secondsand the failure is logged. - Filters are engine-neutral:
new All(new Equals('forum_id', 3), new Range('reply_count', gte: 2)).
Keeping the index fresh
Saving, deleting or restoring a model that belongs to a registered index updates its document
(after the transaction commits). Set FILAGORA_SEARCH_QUEUE=true to do that on the queue. Failures
are logged and never break the save.
php artisan filagora:search:sync-settings # create indexes and apply their settings php artisan filagora:search:reindex --flush # send every searchable row php artisan filagora:search:reindex --index=threads --from-id=5000 --batch-size=200 --sleep-ms=50 php artisan filagora:search:backfill threads filters # one field group, as partial updates php artisan filagora:search:check-health # counts and failed tasks; non-zero on a problem
filagora:doctor also reports the engine's health. With the database engine all of these say
there is nothing to do.
Using Meilisearch
FILAGORA_SEARCH_ENGINE=meilisearch MEILISEARCH_HOST=http://localhost:7700 MEILISEARCH_KEY=your-key
The engine speaks Meilisearch's HTTP API directly. Changes are applied by Meilisearch after it
has answered, so a failure shows up as a failed task; syncSettings() waits for its own tasks and
MeilisearchEngine::waitForTasks() waits for the rest. Every word of a query must match, and a
total that reaches meilisearch.max_total_hits (1000, Meilisearch's counting limit) is reported with
totalIsCapped.
Writing an engine
Implement Filagora\Search\Contracts\SearchEngine, register it, and run the conformance checks in
your tests. If your engine applies writes later, pass a closure that waits until it has caught up:
foreach (EngineConformance::checks($engine, fn () => $engine->waitForTasks()) as $name => $check) { it("conforms: {$name}", $check); }
Install
composer require filagora/filagora-search
Nothing to migrate: the package owns no tables. It uses the database engine until you set
FILAGORA_SEARCH_ENGINE. Packages that have searchable things (forums, cms) register their own
indexes when this package is installed.
Testing
composer test
Tests run against a real MariaDB database named testing.
Licence
MIT. See LICENSE.