Magento 2: Kho sản phẩm, nhóm bộ lọc và `AND`


12

Tôi đang cố gắng sử dụng kho lưu trữ sản phẩm để tìm nạp danh sách các sản phẩm. Tôi muốn tìm nạp dựa trên hai bộ lọc, kết hợp với một ANDtiêu chí, nhưng mọi thứ dường như không hoạt động. Tôi không hiểu làm thế nào các nhóm bộ lọc hoạt động? Hay đây là một lỗi cần được báo cáo?

Cụ thể, (ví dụ ngớ ngẩn vì đơn giản) Tôi có một nhà xây dựng nơi tôi tiêm trình xây dựng bộ lọc, trình tạo nhóm bộ lọc và trình tạo tiêu chí tìm kiếm

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;
}

Sau đó, sau này trong một phương thức, tôi sử dụng các trình tạo bộ lọc để xây dựng hai bộ lọc

    $filter1 = $this->filterBuilder->setField('sku')
            ->setValue('24-MB01')
            ->setConditionType('eq')
            ->create();

    $filter2 = $this->filterBuilder->setField('sku')
            ->setValue('WT08-XS-Black')
            ->setConditionType('eq')
            ->create();

Sau đó, tôi sử dụng trình tạo nhóm bộ lọc để xây dựng nhóm bộ lọc bao gồm hai bộ lọc này

    $filter_group = $this->filterGroupBuilder
        ->addFilter($filter1)
        ->addFilter($filter2)
        ->create();

Sau đó, tôi đã sử dụng trình xây dựng tiêu chí tìm kiếm, đặt nhóm bộ lọc trên đó

    $criteria = $this->searchCriteriaBuilder
        ->setFilterGroups([$filter_group])
        ->setPageSize(100)
        ->create();            
    return $criteria

Cuối cùng, khi tôi sử dụng tiêu chí này với kho lưu trữ sản phẩm (được sử dụng ở nơi khác, bỏ qua hàm tạo và di để tránh nhầm lẫn)

/* @var Magento\Catalog\Api\ProductRepositoryInterface */
$list = $productRepository->getList($searchCriteria);  

Cuộc gọi thành công nhưng tôi nhận lại được hai sản phẩm. tức là bộ lọc SKU được áp dụng như một OR, không phải là một AND. Tôi hy vọng truy vấn này sẽ không trả lại gì.

Nếu tôi đào sâu vào Magento\Catalog\Api\ProductRepositorylớp, và hãy xem quy chế chọn của bộ sưu tập

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;
}               

Tôi thấy các tiêu chí được thêm vào với một 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')) 

Đây có phải là một lỗi? Có cách nào (thiếu dựa vào các bộ sưu tập sản phẩm và bỏ các kho lưu trữ) để làm cho công việc này không?


2
Tôi chưa nhìn vào khu vực này một cách cá nhân, nhưng cyrillschumacher.com/2015/01/02/ có thể hữu ích.
Alan Kent

Câu trả lời:


15

Chú thích thực tế của \Magento\Framework\Api\Search\FilterGroupnói (lớp phpDoc):

Nhóm hai hoặc nhiều bộ lọc lại với nhau bằng cách sử dụng logic OR

Điều đó có nghĩa là bạn cần tạo hai nhóm với mỗi bộ lọc.


Cảm ơn đã làm rõ điều này. Bạn chỉ cần yêu tất cả các lớp trừu tượng trong Magento 2 :-P
Giel Berkers

2

Trong Magento 2, tất cả các bộ lọc trong cùng FilterGroupsẽ được thêm bằng ORtoán tử. Nhưng tất cả FilterGroupsẽ được thêm vào bằng cách sử dụng ANDtoán tử. Vì vậy, bạn sẽ cần thêm nhiều FilterGroups như dưới đây:

$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$searchCriteria = $objectManager->create('\Magento\Framework\Api\SearchCriteria');
$filter = $objectManager->create('\Magento\Framework\Api\Filter');
$filter->setField('category_id');
$filter->setValue(array(1, 2, 3));
$filter->setConditionType('in');

$filterGroup = $objectManager->create('\Magento\Framework\Api\Search\FilterGroup');
$filterGroup->setFilters([$filter]);

$filterEnabled = $objectManager->create('\Magento\Framework\Api\Filter');
$filterEnabled->setField('status');
$filterEnabled->setValue(\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
$filterEnabled->setConditionType('eq');

$filterGroupEnabled = $objectManager->create('\Magento\Framework\Api\Search\FilterGroup');
$filterGroupEnabled->setFilters([$filterEnabled]);


$searchCriteria->setFilterGroups([$filterGroup, $filterGroupEnabled]);

Để biết thêm chi tiết và kết hợp logic về tiêu chí tìm kiếm, bạn có thể tìm thấy tại Tiêu chí tìm kiếm Magento-2


Điều này là không chính xác. Logic được thực hiện trên cơ sở mỗi Kho lưu trữ.
Alan Storm

Xin chào @Alan Storm, đây là giải pháp đã được thử nghiệm. Tôi đã thử nghiệm nó cho cửa hàng mặc định trong Magento 2.1.0. Bạn có bất cứ lời biện minh nào để tuyên bố nó sai không, thưa ông?
Kamal Singh


@Alan Storm, đó là những gì tôi đã đề cập trong câu trả lời của mình. Tất cả các Nhóm bộ lọc được nối bằng toán tử AND và Tất cả các bộ lọc trong một nhóm bộ lọc được nối bằng toán tử OR theo tài liệu tiêu chí tìm kiếm Magento 2. Tôi đã đề cập rằng giải pháp này được thử nghiệm với cửa hàng mặc định. Điều gì làm cho câu trả lời này sai theo nhận xét của bạn, tôi đã không nhận được nó.
Kamal Singh

@KamelSingh Bạn đã đọc báo cáo lỗi tôi liên kết chưa? Bất kể hành vi dự định của họ là gì, hành vi của các bộ lọc và nhóm bộ lọc cuối cùng phụ thuộc vào hành vi của kho lưu trữ mà họ đang ở.
Alan Storm
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.