This bundle integrates elastica-specification with Symfony.
Download bundle using composer :
composer require gbprod/elastica-specification-bundle
Declare in your app/AppKernel.php
file:
<?php
// app/AppKernel.php
public function registerBundles()
{
$bundles = array(
// ...
new GBProd\ElasticaSpecificationBundle\ElasticaSpecificationBundle(),
// ...
);
}
Take a look to Specification and Elastica Specification libraries for more informations.
<?php
namespace GBProd\Acme\CoreDomain\Specification\Product;
use GBProd\Specification\Specification;
class IsAvailable implements Specification
{
public function isSatisfiedBy($candidate): bool
{
return $candidate->isSellable()
&& $candidate->expirationDate() > new \DateTime('now')
;
}
}
<?php
namespace GBProd\Acme\Infrastructure\Elastica\QueryFactory\Product;
use GBProd\ElasticaSpecification\QueryFactory\Factory;
use GBProd\Specification\Specification;
use Elastica\QueryBuilder;
class IsAvailableFactory implements Factory
{
public function build(Specification $spec, QueryBuilder $qb)
{
return $qb->query()->bool()
->addMust()
$qb->query()->term(['available' => "0"]),
)
;
}
}
# src/GBProd/Acme/AcmeBundle/Resource/config/service.yml
services:
acme.elastica.query_factory.is_available:
class: GBProd\Acme\Infrastructure\Elastica\QueryFactory\Product\IsAvailableFactory
tags:
- { name: elastica.query_factory, specification: GBProd\Acme\CoreDomain\Specification\Product\IsAvailable }
# src/GBProd/Acme/AcmeBundle/Resource/config/service.yml
services:
acme.product_repository:
class: GBProd\Acme\Infrastructure\Product\ElasticaProductRepository
arguments:
- "@elastica.client"
- "@gbprod.elastica_specification_handler"
<?php
namespace GBProd\Acme\Infrastructure\Product;
use Elastica\Client;
use Elastica\QueryBuilder;
use GBProd\ElasticaSpecification\Handler;
use GBProd\Specification\Specification;
class ElasticaProductRepository implements ProductRepository
{
private $client;
private $handler;
public function __construct(Client $em, Handler $handler)
{
$this->client = $client;
$this->handler = $handler;
}
public function findSatisfying(Specification $specification)
{
$type = $this
->getIndex('catalog')
->getType('product')
;
$query = $this->handler->handle($specification, new QueryBuilder());
return $type->search($query);
}
}
<?php
$products = $productRepository->findSatisfying(
new AndX(
new IsAvailable(),
new IsLowStock()
)
);
You can specify the Elastica DSL version using dsl_version
configuration node (default: Latest
).
To use a different version, just set it to the version classname.
# app/config/config.yml
elastica_specification_bundle:
dsl_version: Version120