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

Entity Search Bundle Laravel Package

stinger-soft/entity-search-bundle

A Symfony bundle for adding entity search to your application, with configurable search services and Doctrine entity query support. Lightweight, easy to integrate, and designed for flexible search workflows.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the framework reality check. stinger-soft/entity-search-bundle is a Symfony bundle, not a Laravel package.

  • There is no service provider, no config/entity-search.php to publish, no Facade. composer require stinger-soft/entity-search-bundle in a Laravel app will at best install silently and do nothing, and at worst fail resolution because its symfony/* and doctrine/* constraints were written for Symfony 4/5-era versions. Run composer why-not stinger-soft/entity-search-bundle before wasting time.
  • If you are evaluating it, treat it as a reference architecture for "index Doctrine entities into a search backend," not as an installable dependency.

Where to look first (in the repo):

  1. DependencyInjection/Configuration.php — the config tree tells you the whole mental model: which search_service backend is aliased, index naming, and facet settings.
  2. Model/ — the IndexableEntityInterface (roughly getId(), getDocumentType(), and a way to produce the search document).
  3. Service/ — the SearchService / SearchServiceInterface implementations, including the null/dummy backend used for tests.
  4. Document/ (or equivalent) — the DocumentBuilder that turns an entity into a flat, typed document.

The first use case to understand: an entity (e.g. Product) implements the indexable interface; a builder flattens it into a document with typed fields; SearchService::index() writes it to Elasticsearch via Elastica; SearchService::search() returns IDs or entities plus facet counts. That's the entire loop — everything else is configuration.

In Laravel terms, the closest native equivalent is Laravel Scout + a document transformer. Before adopting anything, prototype that: a Searchable model, a toSearchableArray(), and a meilisearch/elasticsearch driver. If that satisfies you, you never needed this bundle.

Implementation Patterns

Pattern A — Borrow the abstraction, not the code (recommended). Mirror the bundle's shape inside Laravel:

  • Define an Indexable contract: getSearchId(): string, getDocumentType(): string, toSearchDocument(): array.
  • Implement a DocumentBuilder service that assembles the array (typed fields, nested objects, denormalized facet values). This is the piece worth stealing — keep it separate from the model so field extraction is testable and versionable.
  • Bind a SearchServiceInterface in a service provider ($this->app->bind(...)) so you can swap Meilisearch ↔ Elasticsearch ↔ a fake in tests, exactly as the bundle swaps backends via its search_service alias.
  • Drive everything through queued jobs: Model::observe() → dispatch IndexEntity/DeleteEntityFromIndex. The bundle has no automatic sync either; you own the lifecycle.

Pattern B — Run it as a sidecar. If you genuinely want the bundle's facet/aggregation logic, stand up a small Symfony app that shares (or duplicates) the Doctrine entities, indexes into Elasticsearch, and exposes a search endpoint. Laravel calls it over HTTP. This is the only sane way to use the actual code from a Laravel app.

Pattern C — Symfony-native (for context). Register the bundle in bundles.php, configure the search service and index, implement the interface on entities, register the indexer as a console command, inject SearchServiceInterface into controllers. Facets are configured declaratively and returned alongside hits.

Integration tips that carry across all three:

  • Keep document building and backend transport in separate services. The bundle's strength is this split; preserve it.
  • Model facets as first-class config objects (field, type, size) rather than raw aggregation arrays scattered in controllers.
  • Version your index mappings alongside code and have a reindex command; the bundle builds documents but does not manage your Elasticsearch mappings for you.
  • Re-hydrate entities in batches from returned IDs (single whereIn), never one query per hit.

Gotchas and Tips

  • Framework mismatch is the headline gotcha. No auto-discovery, no artisan commands, no config publishing. Any tutorial you find will be Symfony-flavored.
  • Adoption risk is real. Zero stars, zero dependents, no external docs. Treat the API as unstable and the project as possibly unmaintained. Pin nothing you can't replace in a day.
  • Dependency conflicts. Symfony/Doctrine/Elastica constraints from the Symfony 4/5 era will likely clash with Laravel 10/11 (symfony/* ^6|^7). Check before planning around it.
  • Elasticsearch coupling. The backend expects a live ES cluster (via Elastica) and an index. Mapping/analyzer drift is the #1 source of "why do my searches return nothing" — the bundle won't fix your mappings.
  • Deletes get forgotten. Indexing on create/update is easy; removing from the index on delete (and cascading deletes, soft deletes, bulk updates that bypass events) is where indexes rot. In Laravel, deleted/forceDeleted observers are mandatory.
  • DocumentType / index name mistakes fail silently — a typo routes documents to a different index and search returns empty rather than erroring. Log json_encode($document) plus the target index name before every write while debugging.
  • Hydration N+1. Search returns identifiers; naïvely loading each one will torch performance. Batch it.
  • Testing without Elasticsearch. Use the bundle's null/dummy search service (or your own fake implementing the interface) so unit tests never need a cluster; reserve real-ES tests for an integration suite.
  • Extension points worth copying: the document builder (custom field extraction, computed facet values), the search-service interface (backend swap), and the facet configuration objects. Those three are the actual value in this repo — port the ideas, skip the dependency.
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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core