6

The question is too close to this topic: Magento 2: Product Repositories, Filter Groups, and `AND`

but is it possible to create criteria with multiple OR and AND?

In my case i would like to create alternative to this code:

/** @var $collection \Magento\Catalog\Model\ResourceModel\Product\Collection */
        $collection = $this->collectionFactory->create();
        $collection->addAttributeToSelect('special_from_date');
        $collection->addAttributeToSelect('special_to_date');
        $collection->addAttributeToSelect('price');
        $collection->addAttributeToSelect('special_price');
        $collection->setVisibility($this->catalogProductVisibility->getVisibleInCatalogIds());

        $collection->addStoreFilter()->addAttributeToFilter(
            'special_from_date',
            [
                'or' => [
                    0 => ['date' => true, 'to' => $todayEndOfDayDate],
                    1 => ['is' => new \Zend_Db_Expr('null')],
                ]
            ],
            'left'
        )->addAttributeToFilter(
            'special_from_date',
            [
                'or' => [
                    0 => ['date' => true, 'from' => $todayStartOfDayDate],
                    1 => ['is' => new \Zend_Db_Expr('null')],
                ]
            ],
            'left'
        )->addAttributeToFilter(
            [
                ['attribute' => 'special_from_date', 'is' => new \Zend_Db_Expr('not null')],
                ['attribute' => 'special_to_date', 'is' => new \Zend_Db_Expr('not null')],
            ]
        )->addAttributeToSort(
            'special_from_date',
            'desc'
        );

The problem is that i have here several wrapped OR conditions and all of them are combined using AND.

26

Yes it is possible

You can create an

\Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
\Magento\Framework\Api\FilterBuilder $filterBuilder
\Magento\Framework\Api\Search\FilterGroupBuilder $filterGroupBuilder

After that define your filters

// AND
$this->searchCriteriaBuilder->addFilter('attribute1','value2');
$this->searchCriteriaBuilder->addFilter('attribute2','value2');

// OR
$attr3 = $this->filterBuilder->setField('attribute3')
            ->setValue('value3')
            ->setConditionType('eq')
            ->create();
$attr4 = $this->filterBuilder->setField('attribute4')
            ->setValue('value4')
            ->setConditionType('eq')
            ->create();

 $filterOr = $this->filterGroupBuilder
            ->addFilter($attr3)
            ->addFilter($attr4)
            ->create();
 $this->searchCriteriaBuilder->setFilterGroups([$filterOr]);

 $searchCriteria = $this->searchCriteriaBuilder->create();

 $this->productRepository->getList($searchCriteria);

GET ==>

attribute1 = 'value1' AND attribute2 = 'value2' AND (attribute3='value3' OR attribute4 = 'value4')

Tell me if you have any other questions

    $attr1 = $this->filterBuilder->setField('attribute1')
        ->setValue('value1')
        ->setConditionType('eq')
        ->create();
    $attr2 = $this->filterBuilder->setField('attribute2')
        ->setValue('value2')
        ->setConditionType('eq')
        ->create();

    $filterOr1 = $this->filterGroupBuilder
        ->addFilter($attr1)
        ->addFilter($attr2)
        ->create();


    $attr3 = $this->filterBuilder->setField('attribute3')
        ->setValue('value3')
        ->setConditionType('eq')
        ->create();
    $attr4 = $this->filterBuilder->setField('attribute4')
        ->setValue('value4')
        ->setConditionType('eq')
        ->create();

    $filterOr2 = $this->filterGroupBuilder
        ->addFilter($attr3)
        ->addFilter($attr4)
        ->create();

    $this->searchCriteriaBuilder->setFilterGroups([$filterOr, $filterOr2]);

    $searchCriteria = $this->searchCriteriaBuilder->create();

    $this->productRepository->getList($searchCriteria);

GET ==>

(attribute1 = 'value1' OR attribute2 = 'value2') AND (attribute3='value3' OR attribute4 = 'value4')
  • Thanks for your answer. This criteria says: attribute1 = 'value2' AND attribute2 = 'value2' AND (attribute3='value3' OR attribute4 = 'value4'). I'm talking about this case: (attribute1 = 'value2' OR attribute2 = 'value2') AND (attribute3='value3' OR attribute4 = 'value4') And more interesting staff is to use OR after this statement as well. – Anthony Nov 10 '17 at 13:08
  • I update my answer you cant find the solution – Mohamed El Mrabet Nov 22 '17 at 21:14
  • 1
    @MohamedElMrabet Thanks for above code snippet. I want (attribute = 'value1') OR (attribute = 'value2' AND attribute = 'value3') OR (attribute = 'value3' AND attribute = 'value4') but i'm not able to achieve this. Can you please help? – chirag dodia Jan 1 at 4:37

Not the answer you're looking for? Browse other questions tagged or ask your own question.