Installation:
composer require ibexa/search
Ensure your project uses PHP 8.3+ and Symfony 7+ (or Ibexa DXP 5.x).
Configuration:
config/bundles.php:
Ibexa\SearchBundle\IbexaSearchBundle::class => ['all' => true],
config/packages/ibexa_search.yaml:
ibexa_search:
search_engines:
default:
engine: ibexa_search_engine_elasticsearch
host: '%env(SEARCH_HOST)%'
port: '%env(int:SEARCH_PORT)%'
First Use Case:
use Ibexa\Search\SearchService;
use Ibexa\Search\Query\Criteria;
$searchService = $this->container->get(SearchService::class);
$criteria = new Criteria();
$criteria->query = new \Ibexa\Search\Query\Query();
$criteria->query->queryString = 'laravel';
$searchResults = $searchService->findContent($criteria);
SearchService: Core service for executing searches.Criteria: Defines search parameters (query, filters, sorting, etc.).Query: Contains the actual search query (e.g., queryString, match, bool).$criteria = new Criteria();
$criteria->query = new Query();
$criteria->query->queryString = 'developer guide';
$results = $searchService->findContent($criteria);
$criteria->filter = new \Ibexa\Search\Query\Criteria\ContentTypeFilter();
$criteria->filter->contentTypeIdentifier = 'article';
$criteria->addFacet('language', new \Ibexa\Search\Query\Facet\TermFacet());
$results = $searchService->findContent($criteria);
$criteria->filter = new \Ibexa\Search\Query\Criteria\FacetFilter();
$criteria->filter->facetName = 'language';
$criteria->filter->facetValue = 'en';
$criteria->sortClauses = [
new \Ibexa\Search\Query\SortClause\FieldSortClause('modified', SortClause::ASCENDING),
];
$criteria->offset = 0;
$criteria->limit = 10;
$results = $searchService->findContent($criteria);
$suggestionService = $this->container->get(\Ibexa\Search\Suggestion\SuggestionService::class);
$suggestions = $suggestionService->getSuggestions('lar', 5);
$spellCheckService = $this->container->get(\Ibexa\Search\SpellCheck\SpellCheckService::class);
$corrections = $spellCheckService->check('laravel', 'en');
SearchEvent::POST_SEARCH) to modify results:
$eventDispatcher->addListener(SearchEvent::POST_SEARCH, function (SearchEvent $event) {
$event->getResults()->addMetadata('custom_key', 'custom_value');
});
SearchEngine interface to integrate with third-party engines (e.g., Solr, Algolia):
class CustomSearchEngine implements SearchEngineInterface {
public function search(Criteria $criteria): SearchResult {
// Custom logic
}
}
SearchRepository for Ibexa-specific content operations:
$repository = $this->container->get(\Ibexa\Core\Repository\Repository::class);
$searchService = $repository->getSearchService();
$builder->add('query', TextType::class, [
'mapped' => false,
]);
Deprecation Warnings:
class_alias usage (removed in v5).Criteria Building:
DateRangeFilter with ISO-8601 formatted strings:
$filter = new \Ibexa\Search\Query\Criteria\DateRangeFilter();
$filter->fieldIdentifier = 'modified';
$filter->rangeStart = '2023-01-01T00:00:00+00:00';
$filter->rangeEnd = '2023-12-31T23:59:59+00:00';
$criteria->filter = $filter;
match query for exact phrases).Performance:
lar* are inefficient. Use queryString for full-text search.$facet->setLimit(10);
Content Type Mismatches:
contentTypeIdentifier matches your Ibexa content type definitions.Spell Check Limitations:
en for English).Log Criteria:
$logger->info('Search Criteria:', [
'query' => $criteria->query->queryString,
'filters' => $criteria->filter,
]);
Check Search Engine Status:
$searchService->getSearchEngine()->ping();
Use SearchResult Metadata:
foreach ($results->getSearchHits() as $hit) {
$logger->info('Hit ID:', $hit->getValue('id'));
}
Custom Data Mappers:
PagerSearchDataMapperInterface to transform search hits into custom objects:
class CustomDataMapper implements PagerSearchDataMapperInterface {
public function mapSearchResult(SearchResult $searchResult): array {
return [
'id' => $searchResult->getValue('id'),
'title' => $searchResult->getValue('title'),
];
}
}
Query Builders:
QueryBuilder to add domain-specific logic:
class ArticleQueryBuilder extends QueryBuilder {
public function forPublishedArticles(): self {
$this->query->queryString = 'is_published:true';
return $this;
}
}
Search Event Subscribers:
$eventDispatcher->addSubscriber(new class implements EventSubscriberInterface {
public function getSubscribedEvents(): array {
return [SearchEvent::POST_SEARCH];
}
public function onPostSearch(SearchEvent $event) {
$event->getResults()->setTotalCount($event->getResults()->getTotalCount() * 2);
}
});
Configuration Overrides:
config/packages/ibexa_search.yaml:
ibexa_search:
search_engines:
default:
engine: ibexa_search_engine_elasticsearch
host: 'localhost'
port: 9200
index_name: 'custom_index'
Use SearchService Directly:
Repository unless necessary. SearchService is more flexible.Leverage SearchResult:
$facets = $results->getFacets();
$total
How can I help you explore Laravel packages today?