Magento 2: Search Repository using SearchCriteriaBuilder, Filter & FilterGroup

This article shows how we can search Magento Repositories using SearchCriteriaBuilder that implements SearchCriteriaInterface. An example is provided of how we can perform search on Product repository in Magento. Similarly, we can search for other entities like Category, Customer, Order, Invoice, CMS Page, CMS Block, etc.

We can add different conditions to build custom search criteria.

Filters

Filter class is used to add custom field, value, and condition type to the search criteria.


$filter
    ->setField("name")
    ->setValue("%laptop%")
    ->setConditionType("like");
  • condition_type is optional.
  • If condition_type is not provided then the default condition_type is set as eq.

Different condition types:


CONDITION   NOTES
eq          Equals
gt          Greater than
gteq        Greater than or equal
lt          Less than
lteq        Less than or equal
moreq       More or equal
neq         Not equal
in          The value can contain a comma-separated list of values.
nin         Not in. The value can contain a comma-separated list of values.
like        The value can contain the SQL wildcard characters when like is specified.
nlike       Not like
notnull     Not null
null        Null
finset      A value within a set of values
nfinset     A value that is not within a set of values.
from        The beginning of a range. Must be used with to.
to          The end of a range. Must be used with from.

Filter Groups

FilterGroup class is used to apply multiple search criteria filters.

For OR condition: Pass filters array inside the FilterGroup class object.
For AND condition: Pass filterGroups array inside the searchCriteria class object.


$filter1
    ->setField("name")
    ->setValue("%laptop%")
    ->setConditionType("like");

$filter2
    ->setField("store_id")
    ->setValue("1")
    ->setConditionType("eq");

$filterGroup1->setFilters([$filter1, $filter2]);

$filter3
    ->setField("url_type")
    ->setValue(1)
    ->setConditionType("eq");

$filterGroup2->setFilters([$filter3]);

$searchCriteria->setFilterGroups([$filterGroup1, $filterGroup2]);

The above code will generate the following conditions:


(name like %laptop% OR store_id eq 1) AND (url_type eq 1)

Sorting

SortOrder is used to apply sorting to the search criteria.

Field and Direction can be passed to the sortOrder object.

Field is the name of the field to sort.
Direction is how we would like to sort the result. The two sorting values are ASC and DESC.


$sortOrder
    ->setField("email")
    ->setDirection("ASC");

$searchCriteria->setSortOrders([$sortOrder]);

Pagination

Limit the number in the result.


$searchCriteria->setPageSize(20); //retrieve 20 or less entities

Set the current page


$searchCriteria
    ->setPageSize(20)
    ->setCurrentPage(2); //show the 21st to 40th entity

The search engine determines the maximum number of results that a query can return.
For Elasticsearch, the default value of 10000 is defined in the module’s etc/di.xml file.

Search Items Using Filters

Below is an example of how we can search Product Repository using Search Criteria Builder.

The ProductRepositoryInterface class has the getList(SearchCriteria $searchCriteria) function which returns the search result object. The object is an instance of the class that implements the interface SearchResultInterface.

FilterBuilder and SearchCriteriaBuilder are used to avoid shared instances, i.e. we will be using create() method in the builder object so that Magento will instantiate a new object (unshared object).


use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Api\FilterBuilder;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Api\Data\ProductInterface;
...
...
$filter = $this->filterBuilder
    ->setField(ProductInterface::NAME)
    ->setValue('%headphone%')
    ->setConditionType('like')
    ->create();

$this->searchCriteriaBuilder->addFilters([$filter]);
$this->searchCriteriaBuilder->setPageSize(20);

$searchCriteria = $this->searchCriteriaBuilder->create();
$productsItems  = $this->productRepository
    ->getList($searchCriteria)
    ->getItems();

Search Items using FilterGroups

Using FilterGroups to add multiple AND and OR conditions to search products.


use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\Api\Search\FilterGroupBuilder;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Api\Data\ProductInterface;
...
...
$filter1 = $this->filterBuilder
    ->setField(ProductInterface::NAME)
    ->setValue("%laptop%")
    ->setConditionType("like")
    ->create();

$filter2 = $this->filterBuilder
    ->setField("store_id")
    ->setValue("1")
    ->setConditionType("eq")
    ->create();

$filterGroup1 = $this->filterGroupBuilder
    ->setFilters([$filter1, $filter2]);

$filter3 = $this->filterBuilder
    ->setField("url_type")
    ->setValue(1)
    ->setConditionType("eq")
    ->create();

$filterGroup2 = $this->filterGroupBuilder
    ->setFilters([$filter3]);

$this->searchCriteriaBuilder
    ->setFilterGroups([$filterGroup1, $filterGroup2]);

$this->searchCriteriaBuilder->setPageSize(20);

$searchCriteria = $this->searchCriteriaBuilder->create();
$productsItems  = $this->productRepository
    ->getList($searchCriteria)
    ->getItems();

Product Repository


use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Api\Data\ProductInterface;

Category Repository


use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Api\Data\CategoryInterface;

CMS Page Repository


use Magento\Cms\Api\PageRepositoryInterface;
use Magento\Cms\Api\Data\PageInterface;

CMS Block Repository


use Magento\Cms\Api\BlockRepositoryInterface;
use Magento\Cms\Api\Data\BlockInterface;

Customer Repository


use Magento\Customer\Api\CustomerRepositoryInterface;
use Magento\Customer\Api\Data\CustomerInterface;

Order Repository


use Magento\Sales\Api\OrderRepositoryInterface;
use Magento\Sales\Api\Data\OrderInterface;

Reference:
1. Searching with repositories
2. Search using REST endpoints

Hope this helps. Thanks.