zhortein/elastic-entity-bundle

This bundle handles doctrine like entities stored in ELK stack.

dev-develop 2025-08-06 06:14 UTC

This package is auto-updated.

Last update: 2025-08-06 06:14:12 UTC


README

PHP Version Symfony Version License

A Symfony bundle that provides Doctrine-like entity management for Elasticsearch, allowing you to work with Elasticsearch documents using familiar ORM patterns.

🚀 Features

Core Entity Management

  • Entity-like Management: Use PHP 8.3+ attributes to define ElasticEntity, ElasticField, and ElasticRelation
  • Relations Support: Handle reference and nested relations between entities
  • Complete CRUD Operations: persist, remove, flush, find, findBy, findOneBy
  • Document Versioning: Optimistic concurrency control with version management
  • Refresh Control: Control when documents are refreshed in the index

Index Management

  • Index Operations: Create, delete, and check index existence
  • Index Settings: Configure shards, replicas, refresh intervals, and analysis settings
  • Index Templates: Create, update, delete, and manage index templates
  • Index Aliases: Create, delete, and manage index aliases
  • Index Information: Retrieve detailed index settings and mappings

Advanced Search & Queries

  • Query Types: Support for match, term, range, bool, and custom queries
  • Full-text Search: Custom analyzers and advanced text analysis
  • Filters & Post-filters: Complex filtering capabilities
  • Multi-column Sorting: Advanced sorting options
  • Pagination: Both offset-based (from/size) and cursor-based (search_after) pagination
  • Result Highlighting: Search result highlighting with customizable options
  • Aggregations: Terms, date histogram, stats, and custom aggregations
  • Scroll API: Efficient processing of large result sets
  • Multi-index Search: Search across multiple indices simultaneously

Bulk Operations

  • Bulk Insert: Efficient batch document creation
  • Bulk Update: Batch document updates
  • Bulk Delete: Batch document deletion
  • Bulk Mixed Operations: Combine different operations in a single request

Maintenance & Performance

  • Reindex API: Copy documents from one index to another with optional filtering
  • Index Refresh: Manual index refresh operations
  • Index Flush: Force index flush operations
  • Cache Management: Clear query, fielddata, and request caches
  • Force Merge: Optimize index segments for better performance

Integration & Development

  • Event System: Lifecycle events (pre/post persist, update, remove)
  • Form Integration: Seamless integration with Symfony Forms
  • Validation: Built-in validation support using Symfony constraints
  • Metrics: Query performance metrics and monitoring
  • Docker Ready: Complete Docker development environment included

📋 Requirements

  • PHP: >= 8.3
  • Symfony: >= 7.3
  • Elasticsearch: >= 8.15

🛠 Installation

1. Install via Composer

composer require zhortein/elastic-entity-bundle

2. Enable the Bundle

The bundle should be automatically enabled. If not, add it to config/bundles.php:

<?php

return [
    // ...
    Zhortein\ElasticEntityBundle\ZhorteinElasticEntityBundle::class => ['all' => true],
];

3. Configure the Bundle

Create config/packages/elastic_entity.yaml:

zhortein_elastic_entity:
    elasticsearch:
        hosts:
            - 'http://localhost:9200'
        retries: 0
        timeout: 30
        connection_timeout: 10
    entity_paths:
        - 'src/Entity'
    auto_mapping: true

🐳 Docker Development Environment

This bundle includes a complete Docker development environment.

Quick Start

# Clone the repository
git clone https://github.com/zhortein/elastic-entity-bundle.git
cd elastic-entity-bundle

# Start the environment
make up

# Install dependencies
make install

# Run tests
make test

# Run code quality checks
make qa

Available Make Commands

make help          # Show all available commands
make install       # Install dependencies and setup the project
make up            # Start Docker environment
make up-kibana     # Start Docker environment with Kibana
make down          # Stop Docker environment
make test          # Run tests
make test-coverage # Run tests with coverage
make lint          # Run PHPStan analysis
make csfix         # Fix code style issues
make cscheck       # Check code style without fixing
make qa            # Run all quality assurance checks
make shell         # Access PHP container shell
make clean         # Clean up Docker resources

📖 Usage

1. Define an Entity

<?php

declare(strict_types=1);

namespace App\Entity;

use Zhortein\ElasticEntityBundle\Attribute\ElasticEntity;
use Zhortein\ElasticEntityBundle\Attribute\ElasticField;
use Zhortein\ElasticEntityBundle\Contracts\ElasticEntityInterface;
use Zhortein\ElasticEntityBundle\Traits\ElasticEntityTrait;

#[ElasticEntity(index: 'products', shards: 1, replicas: 1, refreshInterval: '1s')]
class Product implements ElasticEntityInterface
{
    use ElasticEntityTrait;

    #[ElasticField(type: 'keyword')]
    private string $id;

    #[ElasticField(type: 'text', analyzer: 'standard')]
    private string $name;

    #[ElasticField(type: 'integer')]
    private int $price;

    #[ElasticField(type: 'keyword')]
    private string $category;

    #[ElasticField(type: 'date')]
    private \DateTimeInterface $createdAt;

    // Constructor, getters, and setters...
    
    public function __construct()
    {
        $this->id = uniqid();
        $this->createdAt = new \DateTime();
    }

    public function getId(): string
    {
        return $this->id;
    }

    // ... other getters and setters
}

2. Use the Entity Manager

<?php

declare(strict_types=1);

namespace App\Service;

use App\Entity\Product;
use Zhortein\ElasticEntityBundle\Manager\ElasticEntityManager;

class ProductService
{
    public function __construct(
        private readonly ElasticEntityManager $elasticEntityManager
    ) {
    }

    public function createProduct(string $name, int $price, string $category): Product
    {
        $product = new Product();
        $product->setName($name);
        $product->setPrice($price);
        $product->setCategory($category);

        // Persist the entity
        $this->elasticEntityManager->persist($product);
        $this->elasticEntityManager->flush();

        return $product;
    }

    public function findProduct(string $id): ?Product
    {
        return $this->elasticEntityManager->find(Product::class, $id);
    }

    public function findProductsByCategory(string $category): array
    {
        return $this->elasticEntityManager->findBy(
            Product::class,
            ['category' => $category]
        );
    }

    public function findExpensiveProducts(int $minPrice): array
    {
        return $this->elasticEntityManager->findBy(
            Product::class,
            ['price' => ['_range' => ['gte' => $minPrice]]],
            ['price' => 'desc'],
            10
        );
    }

    public function updateProduct(Product $product): void
    {
        $this->elasticEntityManager->persist($product);
        $this->elasticEntityManager->flush();
    }

    public function deleteProduct(Product $product): void
    {
        $this->elasticEntityManager->remove($product);
        $this->elasticEntityManager->flush();
    }
}

3. Advanced Queries and Aggregations

// Complex search with multiple criteria
$products = $this->elasticEntityManager->findBy(Product::class, [
    'category' => 'electronics',
    'price' => ['_range' => ['gte' => 100, 'lte' => 500]],
    'name' => ['_match' => 'smartphone']
], ['price' => 'asc'], 20, 0);

// Aggregations
$aggregations = $this->elasticEntityManager->aggregate(Product::class, [
    'avg_price' => [
        'avg' => ['field' => 'price']
    ],
    'categories' => [
        'terms' => ['field' => 'category']
    ]
]);

🧪 Testing

The bundle includes comprehensive test suites:

  • Unit Tests: Core functionality testing
  • Integration Tests: Elasticsearch integration testing
  • Functional Tests: End-to-end testing
# Run all tests
make test

# Run tests with coverage
make test-coverage

# Run specific test suite
docker compose run --rm php vendor/bin/phpunit tests/Unit
docker compose run --rm php vendor/bin/phpunit tests/Integration
docker compose run --rm php vendor/bin/phpunit tests/Functional

🔧 Code Quality

The project maintains high code quality standards:

  • PHPStan: Static analysis at maximum level
  • PHP CS Fixer: PSR-12 code style compliance
  • PHPUnit: Comprehensive test coverage
# Run all quality checks
make qa

# Individual checks
make lint      # PHPStan analysis
make cscheck   # Code style check
make csfix     # Fix code style issues

📚 Documentation

📖 User Documentation

🇬🇧 English

🇫🇷 Français

🔧 Developer Documentation

🇬🇧 English

🇫🇷 Français

📋 Project Documentation

🤝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

  1. Fork the repository
  2. Clone your fork
  3. Start the development environment: make up
  4. Install dependencies: make install
  5. Run tests: make test
  6. Make your changes
  7. Run quality checks: make qa
  8. Submit a pull request

📄 License

This project is licensed under the GPL-3.0-or-later License - see the LICENSE file for details.

👥 Authors

  • David Renard - Initial work - Website

🙏 Acknowledgments

  • Symfony community for the excellent framework
  • Elasticsearch team for the powerful search engine
  • All contributors who help improve this bundle

Made with ❤️ for the Symfony community