Magento 2: ที่เก็บผลิตภัณฑ์กลุ่มตัวกรองและ `AND '


12

ฉันกำลังพยายามใช้ที่เก็บผลิตภัณฑ์เพื่อดึงรายการผลิตภัณฑ์ ฉันต้องการดึงข้อมูลตามตัวกรองสองตัวรวมกับ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

ในที่สุดเมื่อฉันใช้เกณฑ์นี้กับที่เก็บผลิตภัณฑ์ (ใช้ที่อื่นโดยไม่ต้องสร้าง constructor และ 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')) 

นี่เป็นข้อบกพร่องหรือไม่? มีวิธี (ขาดการพึ่งพาคอลเลกชันผลิตภัณฑ์โดยตรงและการคัดแยกที่เก็บ) เพื่อใช้งานได้หรือไม่


2
ฉันยังไม่ได้เข้าไปดูบริเวณนี้เป็นการส่วนตัว แต่cyrillschumacher.com/2015/01/02/..อาจมีประโยชน์
Alan Kent

คำตอบ:


15

หมายเหตุประกอบจริงของ\Magento\Framework\Api\Search\FilterGroupsays (คลาส phpDoc):

จัดกลุ่มตัวกรองสองตัวขึ้นไปเข้าด้วยกันโดยใช้ OR แบบลอจิคัล

หมายความว่าคุณต้องสร้างสองกลุ่มโดยมีหนึ่งตัวกรองในแต่ละกลุ่ม


ขอขอบคุณที่แจ้งให้ทราบ คุณต้องรักความเป็นนามธรรมใน Magento 2 :-P
Giel Berkers เมื่อ

2

ใน Magento 2 ตัวกรองทั้งหมดในเดียวกันFilterGroupจะถูกเพิ่มโดยใช้ORโอเปอเรเตอร์ แต่FilterGroupจะเพิ่มทั้งหมดโดยใช้ANDโอเปอเรเตอร์ ดังนั้นคุณจะต้องเพิ่มหลายFilterGroups ดังนี้:

$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]);

ในรายละเอียดเพิ่มเติมและชุดค่าผสมเชิงตรรกะเกี่ยวกับเกณฑ์การค้นหาคุณสามารถค้นหาได้ที่Magento-2 Search Criteria


สิ่งนี้ไม่ถูกต้อง ตรรกะถูกนำไปใช้บนพื้นฐานของพื้นที่เก็บข้อมูล
อลันสตอร์ม

สวัสดี @Alan Storm นี่คือวิธีการแก้ปัญหาการทดสอบ ฉันได้ทำการทดสอบสำหรับร้านค้าเริ่มต้นใน Magento 2.1.0 แล้ว คุณมีเหตุผลใด ๆ ที่จะประกาศว่าผิดครับ
Kamal Singh

@karnalsingh ข้อผิดพลาดนี้: github.com/magento/magento2/issues/4287
Alan Storm

@Alan Storm นั่นคือสิ่งที่ฉันได้กล่าวไว้ในคำตอบของฉัน กลุ่มตัวกรองทั้งหมดจะเข้าร่วมโดยใช้ตัวดำเนินการ AND และตัวกรองทั้งหมดในกลุ่มตัวกรองเดียวจะเข้าร่วมโดยใช้ตัวดำเนินการ OR ตามเอกสารเกณฑ์การค้นหา Magento 2 ฉันได้กล่าวว่าวิธีนี้จะทดสอบกับร้านค้าเริ่มต้น สิ่งที่ทำให้คำตอบนี้ผิดตามความคิดเห็นของคุณฉันไม่ได้รับมัน
Kamal Singh

@KamelSingh คุณอ่านรายงานข้อผิดพลาดที่ฉันเชื่อมโยงแล้วหรือยัง พฤติกรรมของตัวกรองและกลุ่มตัวกรองนั้นขึ้นอยู่กับพฤติกรรมของพื้นที่เก็บข้อมูลในท้ายที่สุด
Alan Storm
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.