Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Showing
with 558 additions and 14 deletions
<?php
declare(strict_types=1);
namespace IQDEV\ElasticSearch\Criteria\Aggs;
use IQDEV\ElasticSearch\Document\Property\Property;
class Aggs
{
public function __construct(
private readonly Property $property,
) {
}
public function getProperty(): Property
{
return $this->property;
}
}
<?php
namespace IQDEV\ElasticSearch\Criteria\Aggs;
use Ramsey\Collection\AbstractCollection;
class AggsCollection extends AbstractCollection
{
/**
* @inheritDoc
*/
public function getType(): string
{
return Aggs::class;
}
}
<?php <?php
namespace IQDEV\ElasticSearch; namespace IQDEV\ElasticSearch\Criteria;
use IQDEV\ElasticSearch\Filter\Collection\FilterCollection; use IQDEV\ElasticSearch\Criteria\Aggs\AggsCollection;
use IQDEV\ElasticSearch\Order\OrderCollection; use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterCollection;
use IQDEV\ElasticSearch\Criteria\Order\OrderCollection;
use IQDEV\ElasticSearch\Criteria\Search\SearchCollection;
final class Criteria final class Criteria
{ {
private SearchCollection $search;
private FilterCollection $filters; private FilterCollection $filters;
private OrderCollection $sorting; private OrderCollection $sorting;
private Pagination $pagination; private Pagination $pagination;
private AggsCollection $aggregations;
public function __construct() public function __construct()
{ {
$this->search = new SearchCollection();
$this->filters = new FilterCollection(); $this->filters = new FilterCollection();
$this->sorting = new OrderCollection(); $this->sorting = new OrderCollection();
$this->pagination = new Pagination(); $this->pagination = new Pagination();
$this->aggregations = new AggsCollection();
} }
public function filters(): FilterCollection public function getSearch(): SearchCollection
{
return $this->search;
}
public function getFilters(): FilterCollection
{ {
return $this->filters; return $this->filters;
} }
public function sorting(): OrderCollection public function getSorting(): OrderCollection
{ {
return $this->sorting; return $this->sorting;
} }
public function pagination(): Pagination public function getPagination(): Pagination
{ {
return $this->pagination; return $this->pagination;
} }
public function getAggs(): AggsCollection
{
return $this->aggregations;
}
public function __clone(): void
{
$this->search = clone $this->search;
$this->filters = clone $this->filters;
$this->sorting = clone $this->sorting;
$this->pagination = clone $this->pagination;
$this->aggregations = clone $this->aggregations;
}
} }
<?php
namespace IQDEV\ElasticSearch\Criteria\Filter\Collection;
use IQDEV\ElasticSearch\Criteria\Filter\Filter;
use IQDEV\ElasticSearch\Criteria\Filter\FilterOperator;
use IQDEV\ElasticSearch\Criteria\Filter\FilterType;
use IQDEV\ElasticSearch\Criteria\Filter\LogicOperator;
use Ramsey\Collection\AbstractCollection;
/**
* @method self add(FilterGroupCollection $item)
*/
class FilterCollection extends AbstractCollection
{
/** @var LogicOperator Тип логической операции для коллекции */
protected LogicOperator $type;
/**
* @param FilterGroupCollection[] $data
*/
public function __construct(array $data = [])
{
parent::__construct($data);
$this->type = LogicOperator::AND;
}
/**
* @inheritDoc
*/
public function getType(): string
{
return FilterGroupCollection::class;
}
/**
* Установка типа логической операции
*
* @param LogicOperator $type
*
* @return $this
*/
public function setLogicalType(LogicOperator $type): self
{
$this->type = $type;
return $this;
}
/**
* Получение типа логической операции
*
* @return LogicOperator
*/
public function getLogicalType(): LogicOperator
{
return $this->type;
}
public function getFilterCollectionByType(FilterType $type): PostFilterCollection|QueryFilterCollection
{
$collection = match ($type) {
FilterType::POST => new PostFilterCollection(),
FilterType::QUERY => new QueryFilterCollection(),
};
$collection->data = array_filter(
$this->toArray(),
static fn (FilterGroupCollection $group) => $group->getFilterType() === $type
);
return $collection;
}
public function getQueryFilterCollection(): QueryFilterCollection
{
$collection = new QueryFilterCollection();
$collection->data = array_filter(
$this->toArray(),
static fn (FilterGroupCollection $group) => $group->getFilterType() === FilterType::QUERY
);
return $collection;
}
public function getPostFilterCollection(): PostFilterCollection
{
$collection = new PostFilterCollection();
$collection->data = array_filter(
$this->toArray(),
static fn (FilterGroupCollection $group) => $group->getFilterType() === FilterType::POST
);
return $collection;
}
public function getKeywordFilters(array $excludeFilter = []): FilterCollection
{
$filterCollection = new FilterCollection();
foreach ($this->data as $filterGroup) {
/** @var FilterGroupCollection $filterGroup */
$keywordFilterGroup = new FilterGroupCollection();
foreach ($filterGroup->data as $filter) {
/** @var Filter $filter */
$field = $filter->field()->value();
if (in_array($field, $excludeFilter, true)
|| in_array($filter->operator(), [
FilterOperator::LT,
FilterOperator::LTE,
FilterOperator::GT,
FilterOperator::GTE
], true)
) {
continue;
}
$keywordFilterGroup->add($filter);
}
if (false === $keywordFilterGroup->isEmpty()) {
$keywordFilterGroup->setLogicOperator($filterGroup->getLogicOperator());
$filterCollection->add($keywordFilterGroup);
}
}
return $filterCollection;
}
public function getNumberFilters(array $excludeFilter = []): FilterCollection
{
$filterCollection = new FilterCollection();
foreach ($this as $filterGroup) {
/** @var FilterGroupCollection $filterGroup */
$numberFilterGroup = new FilterGroupCollection();
foreach ($filterGroup as $filter) {
/** @var Filter $filter */
$field = $filter->field()->value();
if (in_array($field, $excludeFilter, true)) {
continue;
}
if (in_array($filter->operator(), [
FilterOperator::LT,
FilterOperator::LTE,
FilterOperator::GT,
FilterOperator::GTE
], true)) {
$numberFilterGroup->add($filter);
}
}
if (false === $numberFilterGroup->isEmpty()) {
$numberFilterGroup->setLogicOperator($filterGroup->getLogicOperator());
$filterCollection->add($numberFilterGroup);
}
}
return $filterCollection;
}
}
<?php <?php
namespace IQDEV\ElasticSearch\Filter\Collection; namespace IQDEV\ElasticSearch\Criteria\Filter\Collection;
use IQDEV\ElasticSearch\Filter\Filter; use IQDEV\ElasticSearch\Criteria\Filter\Filter;
use IQDEV\ElasticSearch\Filter\FilterType; use IQDEV\ElasticSearch\Criteria\Filter\FilterOperator;
use IQDEV\ElasticSearch\Filter\LogicOperator; use IQDEV\ElasticSearch\Criteria\Filter\FilterType;
use IQDEV\ElasticSearch\Criteria\Filter\LogicOperator;
use Ramsey\Collection\AbstractCollection; use Ramsey\Collection\AbstractCollection;
/** /**
...@@ -13,7 +14,7 @@ use Ramsey\Collection\AbstractCollection; ...@@ -13,7 +14,7 @@ use Ramsey\Collection\AbstractCollection;
class FilterGroupCollection extends AbstractCollection class FilterGroupCollection extends AbstractCollection
{ {
/** @var LogicOperator Тип логической операции для коллекции */ /** @var LogicOperator Тип логической операции для коллекции */
protected LogicOperator $type; protected LogicOperator $logicOperator;
/** @var FilterType Тип фильтра для коллекции */ /** @var FilterType Тип фильтра для коллекции */
protected FilterType $filterType; protected FilterType $filterType;
...@@ -23,8 +24,8 @@ class FilterGroupCollection extends AbstractCollection ...@@ -23,8 +24,8 @@ class FilterGroupCollection extends AbstractCollection
public function __construct(array $data = []) public function __construct(array $data = [])
{ {
parent::__construct($data); parent::__construct($data);
$this->type = new LogicOperator(LogicOperator::AND); $this->logicOperator = LogicOperator::AND;
$this->filterType = FilterType::post(); $this->filterType = FilterType::POST;
} }
/** /**
...@@ -42,9 +43,9 @@ class FilterGroupCollection extends AbstractCollection ...@@ -42,9 +43,9 @@ class FilterGroupCollection extends AbstractCollection
* *
* @return $this * @return $this
*/ */
public function setLogicalType(LogicOperator $type): self public function setLogicOperator(LogicOperator $type): self
{ {
$this->type = $type; $this->logicOperator = $type;
return $this; return $this;
} }
...@@ -54,9 +55,9 @@ class FilterGroupCollection extends AbstractCollection ...@@ -54,9 +55,9 @@ class FilterGroupCollection extends AbstractCollection
* *
* @return LogicOperator * @return LogicOperator
*/ */
public function getLogicalType(): LogicOperator public function getLogicOperator(): LogicOperator
{ {
return $this->type; return $this->logicOperator;
} }
/** /**
...@@ -82,4 +83,39 @@ class FilterGroupCollection extends AbstractCollection ...@@ -82,4 +83,39 @@ class FilterGroupCollection extends AbstractCollection
{ {
return $this->filterType; return $this->filterType;
} }
public function getKeywordFilters(array $excludeFilter = []): FilterGroupCollection
{
return $this->getFilters(false, $excludeFilter);
}
public function getRangeFilters(array $excludeFilter = []): FilterGroupCollection
{
return $this->getFilters(true, $excludeFilter);
}
private function getFilters(bool $range = false, array $excludeFilter = []): FilterGroupCollection
{
$filterGroup = new FilterGroupCollection();
$filterGroup->setLogicOperator($this->getLogicOperator());
foreach ($this->data as $filter) {
/** @var Filter $filter */
$field = $filter->field()->value();
if (false === in_array($field, $excludeFilter, true)
&& $range === in_array($filter->operator(), [
FilterOperator::LT,
FilterOperator::LTE,
FilterOperator::GT,
FilterOperator::GTE
], true)
) {
$filterGroup->add($filter);
}
}
return $filterGroup;
}
} }
<?php <?php
namespace IQDEV\ElasticSearch\Filter\Collection; namespace IQDEV\ElasticSearch\Criteria\Filter\Collection;
class PostFilterCollection extends FilterCollection class PostFilterCollection extends FilterCollection
{ {
......
<?php <?php
namespace IQDEV\ElasticSearch\Filter\Collection; namespace IQDEV\ElasticSearch\Criteria\Filter\Collection;
class QueryFilterCollection extends FilterCollection class QueryFilterCollection extends FilterCollection
{ {
......
<?php <?php
namespace IQDEV\ElasticSearch\Filter; namespace IQDEV\ElasticSearch\Criteria\Filter;
final class Field final class Field
{ {
protected string $value; public function __construct(
protected string $value
public function __construct(string $value) ) {
{
$this->value = $value;
} }
public function value(): string public function value(): string
......
<?php <?php
namespace IQDEV\ElasticSearch\Filter; namespace IQDEV\ElasticSearch\Criteria\Filter;
final class Filter final class Filter
{ {
private Field $field;
private FilterOperator $operator;
private FilterValue $value;
public function __construct( public function __construct(
Field $field, private Field $field,
FilterOperator $operator, private FilterOperator $operator,
FilterValue $value private FilterValue $value
) ) {
{
$this->field = $field;
$this->operator = $operator;
$this->value = $value;
} }
public function field(): Field public function field(): Field
......
<?php
namespace IQDEV\ElasticSearch\Criteria\Filter;
enum FilterOperator: string
{
case EQ = 'eq';
case NE = 'ne';
case GT = 'gt';
case LT = 'lt';
case GTE = 'gte';
case LTE = 'lte';
case CONTAINS = 'contains';
case NOT_CONTAINS = 'not_contains';
}
<?php
namespace IQDEV\ElasticSearch\Criteria\Filter;
enum FilterType
{
case POST;
case QUERY;
}
<?php <?php
namespace IQDEV\ElasticSearch\Filter; namespace IQDEV\ElasticSearch\Criteria\Filter;
interface FilterValue interface FilterValue
{ {
......
<?php
namespace IQDEV\ElasticSearch\Criteria\Filter;
enum LogicOperator: string
{
case AND = 'and';
case OR = 'or';
case NOT = 'not';
}
<?php <?php
namespace IQDEV\ElasticSearch\Filter\Value; namespace IQDEV\ElasticSearch\Criteria\Filter\Value;
use IQDEV\ElasticSearch\Filter\FilterValue; use IQDEV\ElasticSearch\Criteria\Filter\FilterValue;
class FilterKeyword implements FilterValue class FilterKeyword implements FilterValue
{ {
/** @var string|string[] */
public $value;
/** /**
* @param string|string[] $value * @param string|string[]|bool $value
*/ */
public function __construct($value) public function __construct(
{ public string|array|bool $value
$this->value = $value; ) {
} }
/** /**
* @return string|string[] * @return string|string[]|bool
*/ */
public function value() public function value(): string|array|bool
{ {
return $this->value; return $this->value;
} }
......
<?php <?php
namespace IQDEV\ElasticSearch\Filter\Value; namespace IQDEV\ElasticSearch\Criteria\Filter\Value;
use IQDEV\ElasticSearch\Filter\FilterValue; use IQDEV\ElasticSearch\Criteria\Filter\FilterValue;
class FilterNumber implements FilterValue class FilterNumber implements FilterValue
{ {
public float $value;
/** /**
* @param float $value * @param float $value
*/ */
public function __construct( public function __construct(
float $value public float $value
) ) {
{
$this->value = $value;
} }
public function value(): float public function value(): float
......
<?php
declare(strict_types=1);
namespace IQDEV\ElasticSearch\Criteria\Match;
use IQDEV\ElasticSearch\Esable;
class QueryMatch implements Esable
{
public function __construct(
private readonly string $key,
private readonly mixed $value,
) {
}
public function es(): array
{
return [
$this->key => [
'query' => $this->value
]
];
}
}
<?php
declare(strict_types=1);
namespace IQDEV\ElasticSearch\Criteria\Match;
use IQDEV\ElasticSearch\Esable;
use Ramsey\Collection\AbstractCollection;
class QueryMatchCollection extends AbstractCollection implements Esable
{
/**
* @inheritDoc
*/
public function getType(): string
{
return QueryMatch::class;
}
public function es(): array
{
$matches = [];
foreach ($this->toArray() as $match) {
/** @var QueryMatch $match */
$matches = array_merge($match->es());
}
return $matches;
}
}
<?php <?php
namespace IQDEV\ElasticSearch\Order; namespace IQDEV\ElasticSearch\Criteria\Order;
use IQDEV\ElasticSearch\Document\Property\Property; use IQDEV\ElasticSearch\Document\Property\Property;
use IQDEV\ElasticSearch\Esable; use IQDEV\ElasticSearch\Esable;
......
<?php <?php
namespace IQDEV\ElasticSearch\Order; namespace IQDEV\ElasticSearch\Criteria\Order;
use IQDEV\ElasticSearch\Esable; use IQDEV\ElasticSearch\Esable;
use Ramsey\Collection\AbstractCollection; use Ramsey\Collection\AbstractCollection;
......
<?php <?php
namespace IQDEV\ElasticSearch\Order; namespace IQDEV\ElasticSearch\Criteria\Order;
enum OrderDirection: string enum OrderDirection: string
{ {
......