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 340 additions and 98 deletions
......@@ -2,8 +2,18 @@
namespace IQDEV\ElasticSearch\Facet;
use IQDEV\ElasticSearch\Esable;
use IQDEV\ElasticSearch\Document\Property\Property;
interface Facet extends Esable
abstract class Facet implements Facetable
{
public function __construct(
protected Property $property,
protected mixed $value,
) {
}
public function getProperty(): Property
{
return $this->property;
}
}
<?php
namespace IQDEV\ElasticSearch\Facet;
use IQDEV\ElasticSearch\Esable;
final class FacetCategory implements Esable
{
private string $category;
public function __construct(string $category)
{
$this->category = $category;
}
public function es(): array
{
return [
'category_id' => $this->category,
];
}
}
<?php
namespace IQDEV\ElasticSearch\Facet;
use IQDEV\ElasticSearch\Document\Property\Property;
use IQDEV\ElasticSearch\Document\Property\PropertyType;
use IQDEV\ElasticSearch\Facet\Type\BaseFacet;
use IQDEV\ElasticSearch\Facet\Type\KeywordFacet;
use IQDEV\ElasticSearch\Facet\Type\NumberFacet;
class FacetFactory
{
public static function createFromProperty(Property $property, mixed $value): Facet
{
match ($property->getType()) {
PropertyType::KEYWORD => $facet = new KeywordFacet($property, $value),
PropertyType::NUMBER => $facet = new NumberFacet($property, $value),
default => $facet = new BaseFacet($property, $value),
};
return $facet;
}
}
<?php
namespace IQDEV\ElasticSearch\Facet;
final class FacetKeyword implements Facet
{
private string $key;
/** @var string|string[] */
private $value;
/**
* @param string|string[] $value
*/
public function __construct(string $key, $value)
{
$this->key = $key;
$this->value = $value;
}
public function es(): array
{
return [
'facet_code' => $this->key,
'facet_value' => $this->value,
];
}
}
<?php
namespace IQDEV\ElasticSearch\Facet;
final class FacetNumber implements Facet
{
private string $key;
private float $value;
public function __construct(string $key, float $value)
{
$this->key = $key;
$this->value = $value;
}
public function es(): array
{
return [
'facet_code' => $this->key,
'facet_value' => $this->value,
];
}
}
<?php
namespace IQDEV\ElasticSearch\Facet;
use IQDEV\ElasticSearch\Facet\Item\FacetItemCollection;
class FacetResult
{
public FacetItemCollection $products;
protected FacetType $type;
protected string $code;
public function __construct(FacetType $type, string $code)
{
$this->type = $type;
$this->code = $code;
$this->products = new FacetItemCollection();
}
public function getType(): FacetType
{
return $this->type;
}
public function getCode(): string
{
return $this->code;
}
}
<?php
namespace IQDEV\ElasticSearch\Facet;
enum FacetType: string
{
case LIST = 'list';
case RANGE = 'range';
}
<?php
namespace IQDEV\ElasticSearch\Facet;
use IQDEV\ElasticSearch\Esable;
interface Facetable extends Esable
{
}
<?php
namespace IQDEV\ElasticSearch\Facet\Item;
abstract class FacetItem
{
protected ?string $label = null;
protected ?string $value = null;
protected bool $selected = false;
protected int $count = 0;
abstract public static function create(): self;
public function getLabel(): ?string
{
return $this->label;
}
public function getValue(): ?string
{
return $this->value;
}
public function getCount(): int
{
return $this->count;
}
public function isActive(): bool
{
return $this->count > 0;
}
public function isSelected(): bool
{
return $this->selected;
}
}
<?php
namespace IQDEV\ElasticSearch\Facet\Item;
use Ramsey\Collection\AbstractCollection;
class FacetItemCollection extends AbstractCollection
{
public function getType(): string
{
return FacetItem::class;
}
}
<?php
namespace IQDEV\ElasticSearch\Facet\Item;
class FacetItemList extends FacetItem
{
public static function create(
?string $value = null,
int $count = 0,
bool $selected = false,
?string $label = null
): self
{
$instance = new self();
$instance->value = $value;
$instance->label = $label;
$instance->count = $count;
$instance->selected = $selected;
return $instance;
}
}
<?php
namespace IQDEV\ElasticSearch\Facet\Item;
class FacetItemRange extends FacetItem
{
protected FacetItemRangeDTO $data;
protected ?FacetItemRangeDTO $selectedData;
public static function create(
FacetItemRangeDTO $data = null,
FacetItemRangeDTO $selectedData = null,
int $count = 0,
bool $selected = false,
?string $label = null
): self
{
$instance = new self();
$instance->label = $label;
$instance->count = $count;
$instance->selected = $selected;
$instance->data = $data;
$instance->selectedData = $selectedData;
return $instance;
}
public function getFullRange(): array
{
return [
'min' => $this->data->min,
'max' => $this->data->max
];
}
public function getSelectedRange(): array
{
return [
'min' => $this->selectedData->min,
'max' => $this->selectedData->max
];
}
public function getData(): FacetItemRangeDTO
{
return $this->data;
}
public function getSelectedData(): FacetItemRangeDTO
{
return $this->selectedData;
}
}
<?php
namespace IQDEV\ElasticSearch\Facet\Item;
class FacetItemRangeDTO
{
public ?float $min = null;
public ?float $max = null;
public ?float $avg = null;
public ?float $sum = null;
public static function create(?float $min = null, ?float $max = null, ?float $avg = null, ?float $sum = null): self
{
$instance = new self();
$instance->min = $min;
$instance->max = $max;
$instance->avg = $avg;
$instance->sum = $sum;
return $instance;
}
}
\ No newline at end of file
<?php
namespace IQDEV\ElasticSearch\Facet\Item;
class FacetItemSingle extends FacetItem
{
public static function create(?string $value = null, int $count = 0, ?string $label = null): self
{
$instance = new self();
$instance->value = $value;
$instance->count = $count;
$instance->label = $label;
return $instance;
}
}
<?php
namespace IQDEV\ElasticSearch\Facet\Type;
use IQDEV\ElasticSearch\Facet\Facet;
final class BaseFacet extends Facet
{
/**
* @inheritDoc
*/
public function es(): array
{
return [
$this->property->getKey() => $this->value,
];
}
}
<?php
namespace IQDEV\ElasticSearch\Facet\Type;
use IQDEV\ElasticSearch\Facet\Facet;
final class KeywordFacet extends Facet
{
/**
* @inheritDoc
*/
public function es(): array
{
$value = is_array($this->value) ?
array_map(static fn($value) => (string) $value, $this->value) :
(string) $this->value;
return [
'facet_code' => $this->property->getKey(),
'facet_value' => $value
];
}
}
<?php
namespace IQDEV\ElasticSearch\Facet\Type;
use IQDEV\ElasticSearch\Facet\Facet;
final class NumberFacet extends Facet
{
/**
* @inheritDoc
*/
public function es(): array
{
return [
'facet_code' => $this->property->getKey(),
'facet_value' => (float) $this->value,
];
}
}
......@@ -15,12 +15,14 @@ class ArrayHelper
public static function array_filter_recursive(array $array, ?callable $callback = null): array
{
$array = is_callable($callback) ? array_filter($array, $callback) : array_filter($array);
foreach ($array as &$value) {
foreach ($array as $key => &$value) {
if (is_array($value)) {
$value = call_user_func([__CLASS__, __FUNCTION__], $value, $callback);
if (!empty($value)) {
$value = self::array_filter_recursive($value, $callback);
} else {
unset($array[$key]);
}
}
}
......
......@@ -6,19 +6,12 @@ use IQDEV\ElasticSearch\Esable;
final class AddIndex implements Index
{
private string $name;
private Esable $body;
private ?string $id;
public function __construct(
string $name,
Esable $body,
?string $id = null
private string $name,
private Esable $body,
private ?string $id = null
)
{
$this->name = $name;
$this->body = $body;
$this->id = $id;
}
public function es(): array
......
......@@ -4,34 +4,39 @@ namespace IQDEV\ElasticSearch\Indexer;
use IQDEV\ElasticSearch\Configuration;
use IQDEV\ElasticSearch\Document\ProductDocument;
use IQDEV\ElasticSearch\Facet\FacetCategory;
use IQDEV\ElasticSearch\Facet\FacetKeyword;
use IQDEV\ElasticSearch\Facet\FacetNumber;
use IQDEV\ElasticSearch\Document\Property\Property;
use IQDEV\ElasticSearch\Document\Property\PropertyType;
use IQDEV\ElasticSearch\Facet\FacetFactory;
class BaseIndexProvider implements IndexProvider
{
private array $products;
private ?int $size = null;
private ?int $limit = null;
private Configuration $configuration;
public function __construct($products, $configuration)
{
$this->configuration = $configuration;
$this->products = $products;
public function __construct(
private array $products,
private Configuration $configuration
) {
}
public function get(): \Generator
{
foreach ($this->products as $product) {
$document = new ProductDocument(new FacetCategory($product['category']));
$document = new ProductDocument(
FacetFactory::createFromProperty(new Property('category_id', PropertyType::BASE), $product['category'])
);
$document->setAdditionData($product['data'] ?? []);
foreach ($product['properties'] as $type => $values) {
foreach ($values as $key => $prop) {
foreach ($values as $key => $value) {
if ($type === 'number') {
$document->getNumberFacets()->add(new FacetNumber($key, $prop));
$document->getNumberFacets()->add(
FacetFactory::createFromProperty(new Property($key, PropertyType::NUMBER), $value)
);
} else {
$document->getKeywordFacets()->add(new FacetKeyword($key, $prop));
$document->getKeywordFacets()->add(
FacetFactory::createFromProperty(new Property($key, PropertyType::KEYWORD), $value)
);
}
}
}
......