leuchtdiode / opendxp-fulltext-search-bundle
OpenDxp Fulltext Search Bundle
Package info
github.com/leuchtdiode/opendxp-fulltext-search-bundle
Type:symfony-bundle
pkg:composer/leuchtdiode/opendxp-fulltext-search-bundle
Requires
- php: ~8.3.0 || ~8.4.0 || ~8.5.0
- ext-pdo: *
- open-dxp/opendxp: ^1.3
- symfony/config: ^7.0
- symfony/console: ^7.0
- symfony/dependency-injection: ^7.0
- symfony/http-kernel: ^7.0
Requires (Dev)
- phpunit/phpunit: ^13.0
README
Symfony bundle for indexing and searching documents with SQLite FTS5.
What it does
- Collects documents from services that implement
DocumentProviderInterface - Builds a per-collection SQLite database in
OPENDXP_PRIVATE_VAR - Searches the indexed
contentfield with SQLite full-text search - Returns structured results with
id,url,title,description, and optionalpayload
How it works
- You create one or more document providers.
- The bundle indexes all documents for a collection into
fulltext-search--<collection>.sqlite. - The searcher queries that database with SQLite FTS5.
- Results are ranked by
bm25()and paginated withlimitandoffset.
The database is stored at:
OPENDXP_PRIVATE_VAR/fulltext-search--<collection>.sqlite
Requirements
- PHP 8.3+
ext-pdo- SQLite support in PHP
open-dxp/opendxp
Install
composer require leuchtdiode/opendxp-fulltext-search-bundle
Then register the bundle in your Symfony app if it is not auto-registered:
// config/bundles.php return [ // ... Try2catch\OpenDxp\FulltextSearchBundle\OpenDxpFulltextSearchBundle::class => ['all' => true], ];
Create a document provider
Implement DocumentProviderInterface and return an Iterator of FulltextSearchDocument objects.
use ArrayIterator; use Iterator; use Try2catch\OpenDxp\FulltextSearchBundle\DocumentProviderInterface; use Try2catch\OpenDxp\FulltextSearchBundle\Model\FulltextSearchDocument; final class ArticleDocumentProvider implements DocumentProviderInterface { public function getCollection(): string { return 'default'; } public function get(): Iterator { return new ArrayIterator([ new FulltextSearchDocument( id: '123', url: '/articles/123', title: 'Hello world', description: 'Intro article', content: 'This is the searchable content', payload: json_encode(['category' => 'news']), ), ]); } }
If the service is autoconfigured, the bundle tags it automatically as a document provider.
If you want to register it explicitly in config/services.yaml, add the tag yourself:
services: App\FulltextSearch\ArticleDocumentProvider: tags: - { name: 'fulltext_search.document_provider' }
Index documents
Use the console command:
php bin/console fulltext-search:index --collection=default
If --collection is omitted, the command uses default.
Search documents
Inject Try2catch\OpenDxp\FulltextSearchBundle\Searcher and call search() with SearchParams.
use Try2catch\OpenDxp\FulltextSearchBundle\SearchParams; use Try2catch\OpenDxp\FulltextSearchBundle\Searcher; $result = $searcher->search( SearchParams::create() ->setCollection('default') ->setKeyword('hello world') ->setLimit(10) ->setOffset(0) ); foreach ($result->getItems() as $item) { $item->getId(); $item->getUrl(); $item->getTitle(); $item->getDescription(); $item->getPayloadDecoded(); } $total = $result->getTotalCount();
Notes
- Search matches against
content. titleanddescriptionare returned, but are not used for matching.- Payload is stored as a string and can be decoded with
getPayloadDecoded(). - Each collection has its own SQLite file.
- Re-indexing replaces the existing database file for that collection.