atoolo/graphql-search-bundle
Installation Add the bundle via Composer:
composer require sitepark/atoolo-graphql-search-bundle
Enable it in config/bundles.php:
Sitepark\AtooloGraphQLSearchBundle\AtooloGraphQLSearchBundle::class => ['all' => true],
Configuration
Ensure atoolo/search-bundle is installed and configured as a dependency (this bundle extends its functionality).
Review the bundle documentation for required environment variables and Symfony configuration.
First Query
Use the search query in your GraphQL schema. Example:
query SearchContent {
search(
query: "example query"
page: 1
pageSize: 10
) {
results {
id
headline
teaser {
... on MediaTeaser {
image {
url
}
}
}
}
facets {
... on DateFacet {
ranges {
from
to
count
}
}
}
}
}
Search Query Construction
Leverage the search root query with flexible input arguments:
search(
query: String!
page: Int = 1
pageSize: Int = 10
filters: [InputFilter!]
facets: [InputFacet!]
sort: [SortCriteria!]
minHitCount: Int = 0
): SearchResult
InputFilter for dynamic filtering (e.g., source, contentType, dateRange, geoLocated).InputFacet (e.g., date, category, query).SortCriteria (supports spatial, relevance, and custom sorts via SortCriteriaFactory).Teaser Resolvers
The bundle provides resolvers for common teaser types (MediaTeaser, NewsTeaser, TeaserFeature). Extend or override them via dependency injection:
# config/services.yaml
Sitepark\AtooloGraphQLSearchBundle\Resolver\Teaser\MediaTeaserResolver:
tags: ['graphql.resolver']
arguments:
$symbolicAssetFactory: '@atoolo.graphql_search.symbolic_asset_factory'
Server-Side Execution Enable server-side query execution (added in v1.9.0) for complex queries:
search(
query: "complex query"
executeOnServer: true # Offloads processing to the server
)
Context Dispatching
Use the contextDispatcher to modify query behavior dynamically (e.g., URL rewriting, navigation context):
search(
query: "example"
context: {
sameNavigation: true
urlBasePath: "/custom-path"
}
)
Custom Sort Criteria
Implement SortCriteriaFactory to add domain-specific sorting:
namespace App\GraphQL\Sort;
use Sitepark\AtooloGraphQLSearchBundle\Sort\SortCriteriaFactoryInterface;
class CustomSortCriteriaFactory implements SortCriteriaFactoryInterface {
public function evaluate(string $sortCriteria, array $args): array {
return match ($sortCriteria) {
'custom' => ['field' => $args['field'] ?? 'default'],
default => [],
};
}
}
Register it in config/services.yaml:
App\GraphQL\Sort\CustomSortCriteriaFactory:
tags: ['atoolo.graphql_search.sort_factory']
Facet Customization
Extend facet types by creating custom resolvers or modifying the InputFacet input type in your schema.
Image Handling
Use staticImage or symbolicAsset fields for images:
teaser {
... on MediaTeaser {
image {
staticImage {
url
alt
}
symbolicAsset {
url(variant: "large")
accessibilityLabel
}
}
}
}
Spatial Search
Enable geo-based filtering with geoLocated:
search(
filters: [
{ geoLocated: { center: { lat: 48.1351, lon: 11.5820 }, radius: 10 } }
]
)
Pagination and Performance
minHitCount to filter low-relevance results.executeOnServer to avoid client-side timeouts.Deprecation Warnings
symbolicImage was renamed to symbolicAsset in v1.2.0. Update your queries/schema accordingly.headline sort criteria was removed; use custom sorts instead.PHP Version Compatibility
phpstan level 9 requires PHP 8.1+).GeoJSON Edge Cases
null. Handle this in resolvers:
if (empty($geoJsonFeature)) {
return null;
}
Teaser Feature Mismatches
TeaserFeature types in your schema (e.g., actions → teaserFeatures in v1.7.0).Server-Side Execution Limits
executeOnServer may hit memory limits for very large queries. Monitor server logs and adjust max_execution_time if needed.Explain Mode
Use the explain field to analyze query performance:
search(query: "debug", explain: true) {
explain
}
Facets and Filters Validate facet/filter inputs with the GraphQL docs. Example:
search(
facets: [
{ type: "DATE", field: "publishDate", ranges: [{ from: "2023-01-01", to: "2023-12-31" }] }
]
)
Resolver Overrides If a resolver fails, check:
graphql.resolver.SymbolicAssetFactory) are properly bound.URL Rewriting
For urlBasePath or sameNavigation issues, inspect the RewriterContext service:
$this->container->get('atoolo.rewrite.rewriter_context');
Custom Input Types
Extend InputFilter or InputFacet by creating new GraphQL input types and mapping them to the bundle’s underlying search logic.
Query Templates
Use the queryTemplateFilter (v1.8.0+) to pre-configure search queries:
search(
queryTemplate: "news_archive",
templateArgs: { category: "technology" }
)
More Like This
Implement "related content" logic via the moreLikeThis query:
search(
moreLikeThis: {
resourceId: "123",
archive: true
}
)
Spatial Sorting
Customize spatial sorts by extending the SpatialSortCriteria class or overriding the SortCriteriaFactory.
Static Assets
For static images, use the staticImage field with url and alt attributes. Ensure the resolver handles missing keys gracefully (e.g., isset($image['content']['url'])).
How can I help you explore Laravel packages today?