Something went wrong on our end
QueryTest.php 23.96 KiB
<?php
namespace IQDEV\ElasticSearchTests\Filter;
use IQDEV\ElasticSearch\Config\BaseConfiguration;
use IQDEV\ElasticSearch\Converter\Request\CriteriaToRequest;
use IQDEV\ElasticSearch\Criteria\Criteria;
use IQDEV\ElasticSearch\Criteria\Filter\Collection\FilterGroupCollection;
use IQDEV\ElasticSearch\Criteria\Filter\Field;
use IQDEV\ElasticSearch\Criteria\Filter\Filter;
use IQDEV\ElasticSearch\Criteria\Filter\FilterOperator;
use IQDEV\ElasticSearch\Criteria\Filter\FilterType;
use IQDEV\ElasticSearch\Criteria\Filter\Value\FilterKeyword;
use IQDEV\ElasticSearch\Criteria\Filter\Value\FilterNumber;
use IQDEV\ElasticSearch\Criteria\Query\SearchQuery;
use IQDEV\ElasticSearch\Criteria\Search\Search;
use IQDEV\ElasticSearch\Document\Property\Property;
use IQDEV\ElasticSearchTests\AbstractTestCase;
use IQDEV\ElasticSearchTests\Helpers\FormatData;
use IQDEV\ElasticSearchTests\Service\SearchClient;
/**
* Тестирование агрегирующих функций
*/
class QueryTest extends AbstractTestCase
{
public function testFilterChangeFromPostToQuery()
{
$search = [
'category' => [
'key' => 'category_id',
'value' => 'shoes',
],
];
$filter = [
'brand' => [
'key' => 'brand',
'value' => 'nike',
],
'price' => [
'key' => 'price',
'max' => 100.0,
'min' => 10.0,
]
];
$criteria = new Criteria();
$criteria->getSearch()->add(
new Search(
new Property($search['category']['key']),
$search['category']['value'],
),
);
$filterCollectionCategory = new FilterGroupCollection();
$filterCollectionCategory->setFilterType(FilterType::QUERY);
$criteria->getFilters()->add($filterCollectionCategory);
$filterCollectionBrand = new FilterGroupCollection([
new Filter(
new Field($filter['brand']['key']),
FilterOperator::EQ,
new FilterKeyword($filter['brand']['value'])
)
]);
$filterCollectionPrice = new FilterGroupCollection([
new Filter(
new Field($filter['price']['key']),
FilterOperator::LT,
new FilterNumber($filter['price']['min'])
),
new Filter(
new Field($filter['price']['key']),
FilterOperator::GT,
new FilterNumber($filter['price']['max'])
),
]);
// Формирование фильтра для post
$criteriaPost = clone $criteria;
$criteriaPost->getFilters()->add(clone $filterCollectionPrice);
$criteriaPost->getFilters()->add(clone $filterCollectionBrand);
// Формирование фильтра для query
$criteriaQuery = clone $criteria;
$filterTypeQuery = FilterType::QUERY;
$filterCollectionPrice->setFilterType($filterTypeQuery);
$filterCollectionBrand->setFilterType($filterTypeQuery);
$criteriaQuery->getFilters()->add(clone $filterCollectionPrice);
$criteriaQuery->getFilters()->add(clone $filterCollectionBrand);
// Получение классов с данными для запроса в es
$criteriaToRequest = new CriteriaToRequest(new BaseConfiguration());
$requestPost = $criteriaToRequest->fromCriteria($criteriaPost);
$requestQuery = $criteriaToRequest->fromCriteria($criteriaQuery);
$expectedFilter = [
[
"nested" => [
"path" => "search_data",
"query" => [
"bool" => [
"filter" => [
[
"nested" => [
"path" => "search_data.number_facet",
"query" => [
"bool" => [
"filter" => [
[
"term" => [
"search_data.number_facet.facet_code" => $filter['price']['key']
]
],
[
"range" => [
"search_data.number_facet.facet_value" => [
"lt" => $filter['price']['min'],
"gt" => $filter['price']['max'],
]
]
]
]
]
]
]
]
]
]
]
]
],
[
"nested" => [
"path" => "search_data",
"query" => [
"bool" => [
"filter" => [
[
"nested" => [
"path" => "search_data.keyword_facet",
"query" => [
"bool" => [
"filter" => [
[
"term" => [
"search_data.keyword_facet.facet_code" => $filter['brand']['key']
]
],
[
"term" => [
"search_data.keyword_facet.facet_value" => $filter['brand']['value']
]
]
]
]
]
]
]
]
]
]
]
],
];
$expected = [
"query" => [
"bool" => [
"must" => [
[
"term" => [
"category_id" => $search['category']['value']
]
],
]
]
],
];
$this->assertArray(
array_merge($expected, [
"query" => [
"bool" => [
"filter" => $expectedFilter,
]
]
]),
$requestQuery->es(),
'query response'
);
$this->assertArray(
array_merge($expected, [
"post_filter" => [
"bool" => [
"filter" => $expectedFilter,
]
]
]),
$requestPost->es(),
'post response'
);
}
public function testAddingASingleKeyFilterToPostAndQuery()
{
$filter = [
'price' => [
'key' => 'price',
'max' => 100.0,
'min' => 10.0,
'lower' => 0.0,
]
];
$criteria = new Criteria();
$filterCollectionPrice = new FilterGroupCollection([
new Filter(
new Field($filter['price']['key']),
FilterOperator::LT,
new FilterNumber($filter['price']['min'])
),
new Filter(
new Field($filter['price']['key']),
FilterOperator::GT,
new FilterNumber($filter['price']['max'])
),
]);
$criteria->getFilters()->add($filterCollectionPrice);
$filterCollectionQueryPrice = new FilterGroupCollection([
new Filter(
new Field($filter['price']['key']),
FilterOperator::LT,
new FilterNumber($filter['price']['lower'])
),
]);
$filterCollectionQueryPrice->setFilterType(FilterType::QUERY);
$criteria->getFilters()->add($filterCollectionQueryPrice);
$criteriaToRequest = new CriteriaToRequest(new BaseConfiguration());
$request = $criteriaToRequest->fromCriteria($criteria);
$expected = [
"post_filter" => [
"bool" => [
"filter" => [
0 => [
"nested" => [
"path" => "search_data",
"query" => [
"bool" => [
"filter" => [
0 => [
"nested" => [
"path" => "search_data.number_facet",
"query" => [
"bool" => [
"filter" => [
[
"term" => [
"search_data.number_facet.facet_code" => "price"
]
],
[
"range" => [
"search_data.number_facet.facet_value" => [
"lt" => $filter['price']['min'],
"gt" => $filter['price']['max'],
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
],
"query" => [
"bool" => [
"filter" => [
0 => [
"nested" => [
"path" => "search_data",
"query" => [
"bool" => [
"filter" => [
0 => [
"nested" => [
"path" => "search_data.number_facet",
"query" => [
"bool" => [
"filter" => [
0 => [
"term" => [
"search_data.number_facet.facet_code" => "price"
]
],
1 => [
"range" => [
"search_data.number_facet.facet_value" => [
"lt" => $filter['price']['lower']
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
]
];
$this->assertArray($expected, $request->es());
}
public function testGlobalFilterPrice()
{
$filter = [
'price' => [
'key' => 'price',
'min' => 105,
'lower' => 103,
]
];
$criteria = new Criteria();
$filterCollectionPrice = new FilterGroupCollection([
new Filter(
new Field($filter['price']['key']),
FilterOperator::GTE,
new FilterNumber($filter['price']['min'])
)
]);
$criteria->getFilters()->add($filterCollectionPrice);
$filterCollectionQueryPrice = new FilterGroupCollection([
new Filter(
new Field($filter['price']['key']),
FilterOperator::GTE,
new FilterNumber($filter['price']['lower'])
),
]);
$filterCollectionQueryPrice->setFilterType(FilterType::QUERY);
$criteria->getFilters()->add($filterCollectionQueryPrice);
$q = new SearchQuery($criteria);
$handler = SearchClient::getInstance();
$result = $handler->handle($q)->result;
$expected = [
'hits' => [
'h2',
'h3',
'p1',
],
"facets" => [
0 => [
"code" => "brand",
"label" => null,
"type" => "list",
"items" => [
"list" => [
0 => [
"label" => null,
"value" => "nike",
"count" => 1,
"active" => true,
],
1 => [
"label" => null,
"value" => "rebook",
"count" => 2,
"active" => true,
]
],
"range" => [],
],
],
1 => [
"code" => "color",
"label" => null,
"type" => "list",
"items" => [
"list" => [
0 => [
"label" => null,
"value" => "green",
"count" => 0,
"active" => false,
],
1 => [
"label" => null,
"value" => "red",
"count" => 0,
"active" => false,
],
2 => [
"label" => null,
"value" => "white",
"count" => 3,
"active" => true,
],
],
"range" => [],
],
],
2 => [
"code" => "size",
"label" => null,
"type" => "list",
"items" => [
"list" => [
0 => [
"label" => null,
"count" => 0,
"value" => "43",
"active" => false,
],
1 => [
"label" => null,
"value" => "xl",
"count" => 2,
"active" => true,
],
2 => [
"label" => null,
"value" => "xxl",
"count" => 1,
"active" => true,
],
],
"range" => [],
],
],
3 => [
"code" => "price",
"label" => null,
"type" => "range",
"items" => [
"list" => [],
"range" => [
0 => [
"label" => null,
"count" => 3,
"active" => true,
"fullRange" => [
"min" => 103.0,
"max" => 107.0,
],
"activeRange" => [
"min" => 105.0,
"max" => 107.0,
]
]
]
]
]
]
];
$this->assertEqualsCanonicalizing($expected, FormatData::formatDataWFacets($result));
}
public function testGlobalFilterMinPrice()
{
$filter = [
'price' => [
'key' => 'price',
'lower' => 103,
]
];
$criteria = new Criteria();
$filterCollectionQueryPrice = new FilterGroupCollection([
new Filter(
new Field($filter['price']['key']),
FilterOperator::GTE,
new FilterNumber($filter['price']['lower'])
),
]);
$filterCollectionQueryPrice->setFilterType(FilterType::QUERY);
$criteria->getFilters()->add($filterCollectionQueryPrice);
$q = new SearchQuery($criteria);
$handler = SearchClient::getInstance();
$result = $handler->handle($q)->result;
$expected = [
'hits' => [
's4',
'h1',
'h2',
'h3',
'p1',
],
"facets" => [
0 => [
"code" => "brand",
"label" => null,
"type" => "list",
"items" => [
"list" => [
0 => [
"label" => null,
"value" => "nike",
"count" => 3,
"active" => true,
],
1 => [
"label" => null,
"value" => "rebook",
"count" => 2,
"active" => true,
]
],
"range" => [],
],
],
1 => [
"code" => "color",
"label" => null,
"type" => "list",
"items" => [
"list" => [
0 => [
"label" => null,
"value" => "green",
"count" => 1,
"active" => true,
],
1 => [
"label" => null,
"value" => "red",
"count" => 1,
"active" => true,
],
2 => [
"label" => null,
"value" => "white",
"count" => 3,
"active" => true,
],
],
"range" => [],
],
],
2 => [
"code" => "size",
"label" => null,
"type" => "list",
"items" => [
"list" => [
0 => [
"label" => null,
"count" => 1,
"value" => "43",
"active" => true,
],
1 => [
"label" => null,
"value" => "xl",
"count" => 3,
"active" => true,
],
2 => [
"label" => null,
"value" => "xxl",
"count" => 1,
"active" => true,
],
],
"range" => [],
],
],
3 => [
"code" => "price",
"label" => null,
"type" => "range",
"items" => [
"list" => [],
"range" => [
0 => [
"label" => null,
"count" => 5,
"active" => true,
"fullRange" => [
"min" => 103.0,
"max" => 107.0,
],
"activeRange" => [
"min" => 103.0,
"max" => 107.0,
]
]
]
]
]
]
];
$this->assertEqualsCanonicalizing($expected, FormatData::formatDataWFacets($result));
}
}