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
......@@ -2,13 +2,11 @@
namespace IQDEV\ElasticSearchTests\Helpers;
use IQDEV\Search\Document\Product;
use IQDEV\Search\Facet\Facet;
use IQDEV\Search\Facet\Item\FacetItemList;
use IQDEV\Search\Facet\Item\FacetItemRange;
use IQDEV\Search\Facet\Type\FacetListType;
use IQDEV\Search\Facet\Type\FacetRangeType;
use IQDEV\Search\Result;
use IQDEV\ElasticSearch\Document\Product;
use IQDEV\ElasticSearch\Facet\FacetResult;
use IQDEV\ElasticSearch\Facet\Item\FacetItemList;
use IQDEV\ElasticSearch\Facet\Item\FacetItemRange;
use IQDEV\ElasticSearch\Result;
class FormatData
{
......@@ -28,11 +26,11 @@ class FormatData
$aResult = ['facets' => []];
$aResult['hits'] = static::formatData($result)['hits'];
foreach ($result->getFacets() as $facet) {
/** @var Facet $facet */
/** @var FacetResult $facet */
$dataFacet = [
'code' => $facet->getCode(),
'label' => null, // $facet->getLabel(),
'type' => $facet->getType() instanceof FacetRangeType ? 'range' : ($facet->getType() instanceof FacetListType ? 'list' : null),
'type' => $facet->getType()->value,
'items' => [
'list' => [],
'range' => []
......@@ -74,4 +72,37 @@ class FormatData
}
return $aResult;
}
public static function formatDataProducts(Result $result): array
{
$products = [];
/** @var Product $product */
foreach ($result->getProducts() as $product) {
$data = [
'id' => $product->id,
'category' => $product->info['category_id']
];
if ($product->title) {
$data['name'] = $product->title;
}
if (isset($product->info['search_data'])) {
$props = $product->info['search_data'];
if (!empty($props['keyword_facet'])) {
foreach ($props['keyword_facet'] as $prop) {
$data['properties'][$prop['facet_code']] = $prop['facet_value'];
}
}
if (!empty($props['number_facet'])) {
foreach ($props['number_facet'] as $prop) {
$data['properties'][$prop['facet_code']] = $prop['facet_value'];
}
}
}
$products[] = $data;
}
return ['products' => $products];
}
}
\ No newline at end of file
<?php
namespace IQDEV\ElasticSearchTests\Helpers;
use IQDEV\ElasticSearch\Configuration;
use IQDEV\ElasticSearch\Document\ProductDocument;
use IQDEV\ElasticSearch\Document\Property\Property;
use IQDEV\ElasticSearch\Document\Property\PropertyType;
use IQDEV\ElasticSearch\Facet\FacetFactory;
use IQDEV\ElasticSearch\Indexer\AddIndex;
use IQDEV\ElasticSearch\Indexer\DeleteIndex;
use IQDEV\ElasticSearch\Indexer\IndexProvider;
use IQDEV\ElasticSearch\Indexer\UpdateIndex;
class TestIndexProvider implements IndexProvider
{
private Configuration $configuration;
private array $products = [];
public function __construct(Configuration $configuration, array $products)
{
$this->configuration = $configuration;
$this->products = $products;
}
/**
* @inheritDoc
*/
public function get(): \Generator
{
foreach ($this->products as $product) {
$document = new ProductDocument(
FacetFactory::createFromProperty(new Property('category_id', PropertyType::BASE), $product['category'])
);
//todo по-хорошему нужны базовые классы, которые будут описывать свойства
// и формировать структуру для последующей обработки
$data = [
'id' => $product['id'],
];
if (isset($product['name'])) {
$document->setSearchContent($product['name']);
$data['title'] = $product['name'];
}
$document->setAdditionData($data);
if (isset($product['properties'])) {
foreach ($product['properties'] as $key => $value) {
if ($key === 'price') {
$document->getNumberFacets()->add(
FacetFactory::createFromProperty(new Property($key, PropertyType::NUMBER), $value)
);
} else {
$document->getKeywordFacets()->add(
FacetFactory::createFromProperty(new Property($key, PropertyType::KEYWORD), $value)
);
}
}
}
$document->setByConfiguration($this->configuration, 'new', $product['new']);
$document->setByConfiguration($this->configuration, 'rating', $product['rating']);
$product['type'] = $product['type'] ?? null;
switch ($product['type']) {
case 'update':
$document->skipEmpty(true);
$index = new UpdateIndex(
$this->configuration->getIndexName(),
$document,
$product['id']
);
break;
case 'delete':
$index = new DeleteIndex(
$this->configuration->getIndexName(),
$product['id']
);
break;
default:
$index = new AddIndex(
$this->configuration->getIndexName(),
$document,
$product['id']
);
break;
}
yield $index;
}
}
/**
* @inheritDoc
*/
public function setBatchSize(int $size): void
{
}
/**
* @inheritDoc
*/
public function getBatchSize(): ?int
{
return null;
}
/**
* @inheritDoc
*/
public function setLimit(int $limit): void
{
}
/**
* @inheritDoc
*/
public function getLimit(): ?int
{
return null;
}
}
......@@ -4,15 +4,10 @@ namespace IQDEV\ElasticSearchTests\Seed;
use IQDEV\ElasticSearch\Config\BaseConfiguration;
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\Indexer\AddIndex;
use IQDEV\ElasticSearch\Indexer\IndexProvider;
use IQDEV\ElasticSearch\Indexer\IndexRunner;
use IQDEV\ElasticSearchTests\Factory\ClientFactory;
use Psr\Log\Test\TestLogger;
use IQDEV\ElasticSearchTests\Helpers\TestIndexProvider;
use Psr\Log\NullLogger;
class DefaultSeed
{
......@@ -27,112 +22,87 @@ class DefaultSeed
$this->indexRunner = new IndexRunner(
ClientFactory::create(),
$this->configuration,
new TestLogger()
new NullLogger()
);
}
public function start()
{
$provider = new class implements IndexProvider {
public function get(): \Generator
{
$products = [
[
'id' => 's1',
'name' => 'Кроссовки NMD_R1 Boba Fett Spectoo',
'category' => 'shoes',
'properties' => ['brand' => 'adidas', 'color' => 'green', 'size' => 46,'price' => 100]
],
[
'id' => 's2',
'name' => 'КРОССОВКИ ULTRABOOST 5.0 DNA',
'category' => 'shoes',
'properties' => ['brand' => 'adidas', 'color' => 'red', 'size' => 47,'price' => 101]
],
[
'id' => 's3',
'name' => 'Кроссовки Reebok Royal Techque',
'category' => 'shoes',
'properties' => ['brand' => 'rebook', 'color' => 'blue', 'size' => 47,'price' => 102]
],
[
'id' => 's4',
'name' => 'Nike Air Zoom Pegasus 39',
'category' => 'shoes',
'properties' => ['brand' => 'nike', 'color' => 'green', 'size' => 43,'price' => 103]
],
[
'id' => 'h1',
'name' => 'Nike Dri-FIT Strike',
'category' => 't-short',
'properties' => ['brand' => 'nike', 'color' => 'red', 'size' => 'xl','price' => 104]
],
[
'id' => 'h2',
'name' => 'Nike Dri-FIT Rise 365',
'category' => 't-short',
'properties' => ['brand' => 'nike', 'color' => 'white', 'size' => 'xxl','price' => 105]
],
[
'id' => 'h3',
'name' => 'Компрессионная Футболка ACTIVCHILL Graphic Move',
'category' => 't-short',
'properties' => ['brand' => 'rebook', 'color' => 'white', 'size' => 'xl','price' => 106]
],
[
'id' => 'p1',
'name' => 'Товар с ценой',
'category' => 'prices',
'properties' => ['brand' => 'rebook', 'color' => 'white', 'size' => 'xl','price' => 107]
],
];
foreach ($products as $product) {
$document = new ProductDocument(new FacetCategory($product['category']));
//todo по-хорошему нужны базовые классы, которые будут описывать свойства
// и формировать структуру для последующей обработки
$document->setAdditionData([
'id' => $product['id'],
'title' => $product['name'],
]);
foreach ($product['properties'] as $key => $prop) {
if ($key === 'price') {
$document->getNumberFacets()->add(new FacetNumber($key, $prop));
} else {
$document->getKeywordFacets()->add(new FacetKeyword($key, $prop));
}
}
$document->setSearchContent($product['name']);
yield new AddIndex(
$_ENV['IQ_ES_PRODUCT_SEARCH_INDEX'],
$document,
$product['id']
);
}
}
public function setBatchSize(int $size): void
{
}
public function getBatchSize(): ?int
{
return null;
}
public function setLimit(int $limit): void
{
}
public function getLimit(): ?int
{
return null;
}
};
$provider = new TestIndexProvider($this->configuration, [
[
'id' => 's1',
'name' => 'Кроссовки NMD_R1 Boba Fett Spectoo',
'category' => 'shoes',
'properties' => ['brand' => 'adidas', 'color' => 'green', 'size' => 46,'price' => 100],
'year' => 2014,
'new' => false,
'rating' => 3,
],
[
'id' => 's2',
'name' => 'КРОССОВКИ ULTRABOOST 5.0 DNA',
'category' => 'shoes',
'properties' => ['brand' => 'adidas', 'color' => 'red', 'size' => 47,'price' => 101],
'year' => 2023,
'new' => true,
'rating' => 3,
],
[
'id' => 's3',
'name' => 'Кроссовки Reebok Royal Techque',
'category' => 'shoes',
'properties' => ['brand' => 'rebook', 'color' => 'blue', 'size' => 47,'price' => 102],
'year' => 1980,
'new' => false,
'rating' => 3,
],
[
'id' => 's4',
'name' => 'Nike Air Zoom Pegasus 39',
'category' => 'shoes',
'properties' => ['brand' => 'nike', 'color' => 'green', 'size' => 43,'price' => 103],
'year' => 2014,
'new' => true,
'rating' => 5,
],
[
'id' => 'h1',
'name' => 'Nike Dri-FIT Strike',
'category' => 't-short',
'properties' => ['brand' => 'nike', 'color' => 'red', 'size' => 'xl','price' => 104],
'year' => 2010,
'new' => true,
'rating' => 4,
],
[
'id' => 'h2',
'name' => 'Nike Dri-FIT Rise 365',
'category' => 't-short',
'properties' => ['brand' => 'nike', 'color' => 'white', 'size' => 'xxl','price' => 105],
'year' => 2000,
'new' => true,
'rating' => 3,
],
[
'id' => 'h3',
'name' => 'Компрессионная Футболка ACTIVCHILL Graphic Move',
'category' => 't-short',
'properties' => ['brand' => 'rebook', 'color' => 'white', 'size' => 'xl','price' => 106],
'year' => 1990,
'new' => true,
'rating' => 3,
],
[
'id' => 'p1',
'name' => 'Товар с ценой',
'category' => 'prices',
'properties' => ['brand' => 'rebook', 'color' => 'white', 'size' => 'xl','price' => 107],
'year' => 2015,
'new' => false,
'rating' => 3,
],
]);
$this->indexRunner->run($provider);
}
}
\ No newline at end of file
}
......@@ -2,10 +2,10 @@
namespace IQDEV\ElasticSearchTests\Service;
use IQDEV\ElasticSearch\SearchService;
use IQDEV\ElasticSearch\Config\BaseConfiguration as Configuration;
use IQDEV\ElasticSearch\Criteria\Query\SearchQueryHandler;
use IQDEV\ElasticSearch\SearchService;
use IQDEV\ElasticSearchTests\Factory\ClientFactory;
use IQDEV\Search\Query\SearchQueryHandler;
class SearchClient
{
......