Weave Code
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

Elastica Bundle Laravel Package

bok/elastica-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require friendsofsymfony/elastica-bundle
    

    Enable the bundle in config/bundles.php:

    return [
        // ...
        FriendsOfSymfony\ElasticaBundle\FOSElasticaBundle::class => ['all' => true],
    ];
    
  2. Configuration: Add Elasticsearch client config in config/packages/fos_elastica.yaml:

    fos_elastica:
        clients:
            default: { host: localhost, port: 9200 }
        indexes:
            app:
                client: default
                settings:
                    number_of_shards: 3
                types:
                    product:
                        properties:
                            name: ~
                            price: ~
    
  3. First Use Case: Create a Product entity and annotate it for indexing:

    use FriendsOfSymfony\ElasticaBundle\Annotation as Elastica;
    
    #[Elastica\Document(indexName: 'app', type: 'product')]
    class Product
    {
        #[Elastica\Property(name: 'name', type: 'string')]
        private string $name;
    
        #[Elastica\Property(name: 'price', type: 'float')]
        private float $price;
    }
    
  4. Indexing: Run the command to generate and populate the index:

    php bin/console fos:elastica:populate
    

Implementation Patterns

Core Workflows

  1. Entity Indexing:

    • Use annotations (@Document, @Property) or YAML/XML config for mapping.
    • Example YAML config (config/packages/fos_elastica.yaml):
      fos_elastica:
          indexes:
              app:
                  types:
                      product:
                          properties:
                              name: { type: string, analyzer: standard }
                              price: { type: float, scale: 2 }
      
  2. Dynamic Indexing:

    • Skip config and rely on Elasticsearch’s dynamic mapping:
      fos_elastica:
          indexes:
              app:
                  types:
                      dynamic_product: ~
      
  3. Serializer Integration:

    • Configure serializer in fos_elastica.yaml:
      fos_elastica:
          serializer:
              name: fos_elastica.serializer.default
      
    • Use JmsSerializer or Symfony’s Serializer for custom serialization.
  4. Doctrine Listeners:

    • Auto-index entities on postPersist, postUpdate, postRemove:
      fos_elastica:
          listeners:
              ~: true  # Enable all listeners
      
  5. Querying:

    • Create a repository class:
      use FriendsOfSymfony\ElasticaBundle\Repository;
      
      class ProductRepository extends Repository
      {
          public function findByName($name)
          {
              return $this->createQueryBuilder()
                  ->addMust('match', ['name' => $name])
                  ->getQuery()
                  ->getResults();
          }
      }
      
    • Use in controllers:
      $products = $this->get('fos_elastica.finder.product')->find($query);
      
  6. Bulk Operations:

    • Use the populate command for initial data load:
      php bin/console fos:elastica:populate
      
    • For incremental updates, use reindex:
      php bin/console fos:elastica:reindex
      

Integration Tips

  1. Symfony Forms:

    • Use ElasticaType for search forms:
      use FriendsOfSymfony\ElasticaBundle\Form\Type\ElasticaType;
      
      $builder->add('search', ElasticaType::class, [
          'finder' => $this->get('fos_elastica.finder.product'),
          'property' => 'name',
          'multiple' => true,
      ]);
      
  2. API Platform:

    • Extend ElasticaBundle with ApiPlatform for GraphQL/REST search:
      # config/packages/api_platform.yaml
      api_platform:
          formats:
              jsonld:
                  mime_types: ['application/ld+json']
          patch_formats:
              json: true
              jsonld: true
      
  3. Cron Jobs:

    • Schedule reindexing via cron:
      0 3 * * * php /path/to/your/project/bin/console fos:elastica:reindex
      
  4. Testing:

    • Use ElasticaTestCase for unit tests:
      use FriendsOfSymfony\ElasticaBundle\Tests\ElasticaTestCase;
      
      class ProductTest extends ElasticaTestCase
      {
          public function testIndexing()
          {
              $this->assertTrue($this->get('fos_elastica.index.product')->exists('test_id'));
          }
      }
      

Gotchas and Tips

Pitfalls

  1. Index Naming Conflicts:

    • Ensure indexName in @Document matches the config. Mismatches cause silent failures.
    • Fix: Validate with:
      php bin/console fos:elastica:validate
      
  2. Dynamic Mapping Overrides:

    • Dynamic mapping may override explicit types. Disable it in config:
      fos_elastica:
          indexes:
              app:
                  settings:
                      mapping:
                          dynamic: strict
      
  3. Serializer Conflicts:

    • If using JmsSerializer, ensure no circular references exist in entities.
    • Fix: Add @MaxDepth to annotations or configure serializer groups.
  4. Listener Order:

    • Doctrine listeners may fire out of order. Use @Order to prioritize:
      #[Elastica\Listener(order: 100)]
      class CustomListener
      {
          // ...
      }
      
  5. Bulk Indexing Limits:

    • Large datasets may hit Elasticsearch’s bulk API limits (~1000 docs/batch).
    • Fix: Adjust batch size in fos_elastica.yaml:
      fos_elastica:
          batch_size: 500
      
  6. Case Sensitivity:

    • Elasticsearch is case-sensitive by default. Use keyword type for exact matches:
      properties:
          sku: { type: keyword }
      

Debugging

  1. Enable Logging: Add to config/packages/monolog.yaml:

    monolog:
        handlers:
            elastica:
                type: stream
                path: "%kernel.logs_dir%/elastica.log"
                level: debug
    
  2. Query Debugging: Use getQuery()->getElasticaQuery() to inspect raw queries:

    $query = $this->get('fos_elastica.finder.product')->createQueryBuilder()
        ->addMust('match', ['name' => 'test'])
        ->getQuery();
    
    dump($query->getElasticaQuery()->getQuery());
    
  3. Index Validation: Run:

    php bin/console fos:elastica:validate
    

    Fix errors before populating.


Extension Points

  1. Custom Processors:

    • Implement Elastica\Processor\ProcessorInterface for pre/post-indexing logic:
      use FriendsOfSymfony\ElasticaBundle\Processor\ProcessorInterface;
      
      class CustomProcessor implements ProcessorInterface
      {
          public function process($document, $indexName, $typeName)
          {
              $document['custom_field'] = 'value';
              return $document;
          }
      }
      
    • Register in services.yaml:
      services:
          App\Processor\CustomProcessor:
              tags:
                  - { name: fos_elastica.processor, index: app, type: product }
      
  2. Event Subscribers:

    • Subscribe to fos_elastica.index events:
      use FriendsOfSymfony\ElasticaBundle\Event\IndexEvent;
      
      class CustomSubscriber implements EventSubscriberInterface
      {
          public static function getSubscribedEvents()
          {
              return [
                  IndexEvent::INDEX => 'onIndex',
              ];
          }
      
          public function onIndex(IndexEvent $event)
          {
              $event->getDocument()['custom'] = true;
          }
      }
      
  3. Custom Finder:

    • Extend Finder for project-specific logic:
      use FriendsOfSymfony\ElasticaBundle\Finder\FinderInterface;
      
      class CustomFinder extends Finder implements FinderInterface
      {
          public function findOneByCustom($criteria)
          {
              // Custom logic
          }
      }
      
    • Override in services.yaml:
      services:
          fos_elastica.finder.product:
              class: App\Finder\CustomFinder
      
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.
comsave/common
alecsammon/php-raml-parser
chrome-php/wrench
lendable/composer-license-checker
typhoon/reflection
mesilov/moneyphp-percentage
mike42/gfx-php
bookdown/themes
aura/view
aura/html
aura/cli
povils/phpmnd
nayjest/manipulator
omnipay/tests
psr-mock/http-message-implementation
psr-mock/http-factory-implementation
psr-mock/http-client-implementation
voku/email-check
voku/urlify
rtheunissen/guzzle-log-middleware