Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine Entity Search Bundle Laravel Package

stinger-soft/doctrine-entity-search-bundle

A Symfony bundle that adds full-text search to Doctrine entities: index chosen fields, then query records through a simple search service and get ranked results without writing custom DQL. Drop it into existing Symfony and Doctrine projects to make entity data searchable with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

This bundle is the Doctrine ORM bridge for EntitySearchBundle — it supplies the query-building layer, while the parent bundle defines the search contract your entities implement. Treat it as a thin integration, not a full search engine.

  1. Install both bundles. You almost certainly need the sibling package too:
    composer require stinger-soft/entity-search-bundle stinger-soft/doctrine-entity-search-bundle
    
  2. Register the bundles in config/bundles.php (Flex may not auto-register a zero-install package):
    StingerSoft\EntitySearchBundle\EntitySearchBundle::class => ['all' => true],
    StingerSoft\DoctrineEntitySearchBundle\DoctrineEntitySearchBundle::class => ['all' => true],
    
  3. Look first at the parent bundle's interface — the Doctrine bundle exists to satisfy whatever SearchableEntityInterface/SearchServiceInterface the parent defines. That interface is your actual API surface; the Doctrine package just wires it to an EntityManager.
  4. First use case: mark a single entity as searchable by returning its field names, then inject the search service and run a free-text query:
    class Product implements SearchableEntityInterface
    {
        public function getSearchableFields(): array
        {
            return ['name', 'sku', 'description'];
        }
    }
    
    public function search(SearchServiceInterface $search, string $term): array
    {
        return $search->search($term, Product::class);
    }
    
  5. Verify namespaces against the repo before committing to the API — with 0 stars and no dependents there is no ecosystem documentation to fall back on.

Implementation Patterns

Per-entity field declaration. The idiomatic pattern is to let each entity describe its own search surface via the interface method rather than centralising a field map. This keeps search logic colocated with the schema and survives entity refactors.

Weighted / prioritised fields. Most implementations of this style accept an associative array where the key is the field and the value is a weight or ordering hint (['name' => 10, 'description' => 1]). Check the interface signature — if it returns a flat array, fall back to ordering by relevance manually or via a secondary ORDER BY.

Controller-level wiring. Inject the service via autowiring into a controller action, bind ?q= from the request, and hand the term straight in. Keep pagination outside the search call:

  • Run search() to get a QueryBuilder or result set, then attach KnpPaginator/Pagerfanta adapters.
  • If the package returns a Query, wrap it in a Doctrine adapter rather than ->getResult() directly, so you preserve paging.

Query customisation hook. If the returned object is a QueryBuilder, the common extension pattern is to grab it post-build and add your own andWhere() — e.g. filtering to active = true or scoping to a tenant. Do this in a small domain service rather than the controller so the scoping is testable.

Multi-entity search. For a site-wide search box, loop over your searchable entity classes, call the service per class, and merge/sort results in PHP. There is generally no cross-entity relevance ranking built in — normalise scores yourself if you need a unified feed.

Testing. Because the implementation is Doctrine-bound, integration-test against a real (SQLite) connection rather than mocking the EntityManager. Assert on returned identifiers, not on generated DQL strings.

Gotchas and Tips

  • This is a LIKE-based implementation, not a full-text index. Expect LIKE %term% semantics: leading wildcards kill index usage and performance degrades linearly on large tables. For anything beyond small datasets, reach for a real search backend (Elastic/Meilisearch) rather than pushing this bundle harder.
  • Case sensitivity varies by platform. MySQL's default collation is case-insensitive; PostgreSQL LIKE is case-sensitive. If the bundle doesn't normalise this (likely a plain LIKE), searches behave differently between dev SQLite, staging MySQL, and prod Postgres. Test on your production engine.
  • Parameter binding is not guaranteed by convention. If you extend the query builder yourself, never interpolate the raw search term into DQL — always setParameter(). A zero-audience package may not have had security review.
  • Empty / whitespace-only terms. Many implementations of this style either match everything or throw on an empty term. Guard in your controller: return an empty result or an unfiltered listing deliberately rather than relying on bundle defaults.
  • Hydration mode. If the service returns entities, watch out for N+1 when rendering results. Add ->select()/->leftJoin() fetches on the returned QueryBuilder if it exposes one.
  • Unmaintained risk. With 0 stars and 0 dependents, assume no security patches. Pin the version in composer.json, and consider vendoring or forking the ~few hundred lines of query-building if the dependency becomes load-bearing.
  • Config quirks. Bundle config (if any) usually lives under doctrine_entity_search: in config/packages/. Check the bundle's DependencyInjection/Configuration.php in the repo — that file is the authoritative reference when docs are absent.
  • Extension points. The cleanest customisation is decorating the search service (Symfony service decoration) rather than subclassing; it keeps your overrides upgrade-safe if a fork ever lands.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk