Я пытаюсь использовать репозиторий продуктов, чтобы получить список продуктов. Я хочу получить данные на основе двух фильтров в сочетании с AND
критериями, но, похоже, что-то не работает. Я не понимаю, как работают группы фильтров? Или это ошибка, о которой нужно сообщить?
В частности, (глупый пример для простоты) у меня есть конструктор, в который я вставляю построитель фильтров, построитель групп фильтров и построитель критериев поиска
public function __construct(
\Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
\Magento\Framework\Api\FilterBuilder $filterBuilder,
\Magento\Framework\Api\Search\FilterGroupBuilder $filterGroupBuilder
)
{
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
$this->filterBuilder = $filterBuilder;
$this->filterGroupBuilder = $filterGroupBuilder;
}
Затем, позже в методе, я использую построители фильтров для создания двух фильтров
$filter1 = $this->filterBuilder->setField('sku')
->setValue('24-MB01')
->setConditionType('eq')
->create();
$filter2 = $this->filterBuilder->setField('sku')
->setValue('WT08-XS-Black')
->setConditionType('eq')
->create();
Затем я использую построитель группы фильтров для создания группы фильтров, состоящей из этих двух фильтров.
$filter_group = $this->filterGroupBuilder
->addFilter($filter1)
->addFilter($filter2)
->create();
Затем я использовал построитель критериев поиска, установил для него группу фильтров
$criteria = $this->searchCriteriaBuilder
->setFilterGroups([$filter_group])
->setPageSize(100)
->create();
return $criteria
Наконец, когда я использую этот критерий с репозиторием продукта (используется в другом месте, оставляя конструктор и di, чтобы избежать путаницы)
/* @var Magento\Catalog\Api\ProductRepositoryInterface */
$list = $productRepository->getList($searchCriteria);
Звонок успешен, но я вернул два продукта. т.е. фильтр SKU был применен как, а OR
не как AND
. Я ожидаю, что этот запрос ничего не даст.
Если я покопаюсь в Magento\Catalog\Api\ProductRepository
классе и посмотрю на избранный устав коллекции
protected function addFilterGroupToCollection(
\Magento\Framework\Api\Search\FilterGroup $filterGroup,
Collection $collection
) {
//...
if ($fields) {
$collection->addFieldToFilter($fields);
}
//printf lives in my heart forever
echo($collection->getSelect()->__toString());
exit;
}
Я вижу критерии, добавленные с OR
SELECT `e`.*, IF(at_status.value_id > 0, at_status.value, at_status_default.value) AS `status`, IF(at_visibility.value_id > 0, at_visibility.value, at_visibility_default.value) AS `visibility`
FROM `catalog_product_entity` AS `e`
INNER JOIN `catalog_product_entity_int` AS `at_status_default` ON (`at_status_default`.`entity_id` = `e`.`entity_id`) AND (`at_status_default`.`attribute_id` = '94') AND `at_status_default`.`store_id` = 0 LEFT JOIN `catalog_product_entity_int` AS `at_status` ON (`at_status`.`entity_id` = `e`.`entity_id`) AND (`at_status`.`attribute_id` = '94') AND (`at_status`.`store_id` = 1)
INNER JOIN `catalog_product_entity_int` AS `at_visibility_default` ON (`at_visibility_default`.`entity_id` = `e`.`entity_id`) AND (`at_visibility_default`.`attribute_id` = '96') AND `at_visibility_default`.`store_id` = 0 LEFT JOIN `catalog_product_entity_int` AS `at_visibility` ON (`at_visibility`.`entity_id` = `e`.`entity_id`) AND (`at_visibility`.`attribute_id` = '96') AND (`at_visibility`.`store_id` = 1)
WHERE ((`e`.`sku` = '24-MB01') OR (`e`.`sku` = 'WT08-XS-Black'))
Это ошибка? Есть ли способ (если не полагаться непосредственно на коллекции продуктов и отказаться от репозиториев), чтобы сделать эту работу?
источник
Ответы:
Фактическая аннотация
\Magento\Framework\Api\Search\FilterGroup
говорит (класс phpDoc):Это означает, что вам нужно создать две группы с одним фильтром в каждой.
источник
В Magento 2 все фильтры
FilterGroup
будут добавлены с помощьюOR
оператора. Но всеFilterGroup
будет добавлено с помощьюAND
оператора. Так что вам нужно будет добавить несколькоFilterGroup
s, как показано ниже:Более подробную информацию и логические комбинации о критериях поиска вы можете найти в Magento-2 Критерии поиска.
источник