novactive/ezsolrsearchextrabundle
An eZ Platform bundle that extends the Solr search handler with binary file text indexing, a configurable FullText criterion with field and date boosts, custom field setup, exact-match boosting, and admin-managed stopwords and synonyms.
First, the context shift. This is not a Laravel package. It is a Symfony bundle for eZ Platform / Ibexa (the ezsystems/ezplatform-solr-search-engine world). If you are coming from Laravel, map it like this:
| Laravel | Here |
|---|---|
| Service provider | Bundle class + DependencyInjection/Extension |
config/*.php |
YAML under ez_search_engine_solr / bundle config, or app/config/config.yml |
config/app.php providers list |
AppKernel::registerBundles() (eZ 2.x) or config/bundles.php (Symfony 4+/Ibexa) |
| Facades | Constructor injection of eZ\Publish\API\Repository\SearchService |
| Artisan commands | bin/console ezplatform:solr:* / ibexa:* (name varies by version) |
Minimal install
composer require ezsystems/ezplatform-solr-search-engine, point ez_search_engine_solr at a running Solr with the shipped configset, and run a reindex. If vanilla search is broken, this bundle will only confuse the diagnosis.composer require novactive/ezsolrsearchextrabundle.Novactive\Bundle\eZSolrSearchExtraBundle\NovaeZSolrSearchExtraBundle in your kernel/bundles list.bin/console cache:clear.Where to look first
doc/file_indexation.md — binary/plain-text indexing into the fulltext field.doc/fulltext_criterion.md — the extended FullText criterion (multi-field boost, publish-date boost, phrase boost, exact-match boost). This is the file 90% of your day-to-day use comes from.Resources/config/ — service definitions and DI aliases; this is where you find extension points and what the bundle actually decorates.composer.json — the eZ Platform version constraint. Match it to your install before anything else.First use case (30 minutes): take an existing content search that uses the stock FullText criterion and swap it for the bundle's extended criterion so title outranks body, with a mild recency boost. One criterion, no schema changes if the fields are already indexed. That gives you an immediate relevance win and validates the bundle is wired up.
Reindex, once, so you have a baseline:
bin/console ezplatform:solr:index --no-interaction # or ibexa:reindex, depending on version
Pattern 1 — Boost profiles in configuration, not in code. The most common real-world need is "marketing wants titles to weigh more." Hardcoding the boost map into a controller means a deploy every time they change their mind. Load boasweights from a parameter:
parameters:
search.boost.title: 3.0
search.boost.body: 1.0
search.boost.recency: 0.5
Then inject them into your search service and build the criterion once, in one place. Keep a single ContentSearchFactory that owns the criterion construction; never assemble it ad hoc in controllers.
Pattern 2 — Wrap SearchService, don't call it directly.
Every controller and repository that injects SearchService directly will eventually need the same pagination, the same score handling, the same fallback when a criterion option is unsupported. One App\Search\ContentSearcher with search(SearchQuery $q): SearchResult keeps it consistent and gives you one place to log the generated Solr query.
Pattern 3 — Extended FullText criterion, shaped like this:
use eZ\Publish\API\Repository\Values\Content\Query;
use Novactive\Bundle\eZSolrSearchExtraBundle\...\Criterion\FullText; // confirm FQCN in doc/
$query = new Query();
$query->query = new FullText(
$userInput,
[
// option keys below are illustrative — the authoritative list is
// doc/fulltext_criterion.md in the installed version
'boost' => ['title' => 3.0, 'body' => 1.0],
'boostPublishDate' => 0.5,
'boostPhrase' => 2.0,
'boostExact' => 4.0,
]
);
Verify the option names against the doc shipped with your installed version — these bundles rename keys between minor releases, and an unrecognized key typically fails silently rather than throwing.
Pattern 4 — File text indexation.
Enable it only where you need it. The pattern is: the bundle maps binary file content's extracted text into the fulltext field, which means Solr must actually have a text extractor available (Tika or the Solr extract handler, depending on your Solr version and configset). Workflow:
doc/file_indexation.md.bin/console reindex one Content ID rather than the whole tree if your version supports it.Pattern 5 — Versioned reindexing with core swap. For anything beyond a dev box: index into a new core, verify document counts and a handful of queries, then repoint the alias. This bundle's changes touch indexing, so a partial in-place reindex can leave you with a mixed index that returns inconsistent relevance and is miserable to debug.
Pattern 6 — Integration test against a real Solr. Unit-testing the criterion object only proves it serializes. Spin Solr up in CI (Docker, with the eZ configset), index a small fixture set, and assert ordering: "searching 'foo' returns the exact-title hit first." Relevance assertions are the only tests that catch boost regressions.
NOASSERTION. Open the LICENSE file and get sign-off before shipping this in a commercial product. Packagist not being able to classify it is a red flag worth resolving early, not at release time.*:* query sorted/faceted on that field.maxStringLength/field size limits, and note that extracted text is not free at query time either. Monitor core size after rollout.?debug=1-style flag in your install, use it; otherwise log from your wrapper service.cache:clear is the #1 source of "my change did nothing."Resources/config/: the decorated search handler / criterion visitors (to add your own criterion type), and field mappers (to index custom fields into the fulltext field). Decorate rather than patch — the subtree split means your patch has no upstream home.composer.json constraints against your install before debugging anything else.How can I help you explore Laravel packages today?