searchCriteriaBuilder using multiple sort
-
13-04-2021 - |
Question
I've been experimenting with SearchCriteriaBuilder but I can't seem to get the syntax right to apply multiple sort.
I've tried this
$this->searchCriteriaBuilder->addFilter(EntryInterface::STATUS, 1, 'eq');
$sort = [];
$sort[] = $this->sortOrder->setField(EntryInterface::COUNTRY)
->setDirection(SortOrder::SORT_ASC);
$sort[] = $this->sortOrder->setField(EntryInterface::SORT)
->setDirection(SortOrder::SORT_ASC);
$this->searchCriteriaBuilder->setSortOrders($sort);
$searchCriteria = $this->searchCriteriaBuilder->create();
return $this->entryRepositoryInterface->getList($searchCriteria)->getItems();
And this...
$this->searchCriteriaBuilder->addFilter(EntryInterface::STATUS, 1, 'eq');
$sortOne = $this->sortOrder->setField(EntryInterface::COUNTRY)
->setDirection(SortOrder::SORT_ASC);
$sortTwo = $this->sortOrder->setField(EntryInterface::SORT)
->setDirection(SortOrder::SORT_ASC);
$this->searchCriteriaBuilder->setSortOrders([$sortOne, $sortTwo]);
$searchCriteria = $this->searchCriteriaBuilder->create();
return $this->entryRepositoryInterface->getList($searchCriteria)->getItems();
One more I tried
[...]
$this->searchCriteriaBuilder->setSortOrders([$sortOne]);
$this->searchCriteriaBuilder->setSortOrders([$sortTwo]);
[...]
But only one sort applies.
I've checked the docs and I'm still unsure.
Is it possible to apply multiple sorts?
Solution
The reason it doesn't work for you is that $this->sortOrder is a singleton object. So $sortOne and $sortTwo are referred to the same object.
$sortOne = $this->sortOrder->setField(EntryInterface::COUNTRY)
->setDirection(SortOrder::SORT_ASC);
$sortTwo = $this->sortOrder->setField(EntryInterface::SORT)
->setDirection(SortOrder::SORT_ASC);
The solution here is to use SortOrderFactory to create $sortOne and $sortTwo object. E.g.
$this->searchCriteriaBuilder->addFilter(EntryInterface::STATUS, 1, 'eq');
$sortOne = $this->sortOrderFactory->create()->setField(EntryInterface::COUNTRY)
->setDirection(SortOrder::SORT_ASC);
$sortTwo = $this->sortOrderFactory->create()->setField(EntryInterface::SORT)
->setDirection(SortOrder::SORT_ASC);
$this->searchCriteriaBuilder->setSortOrders([$sortOne, $sortTwo]);
$searchCriteria = $this->searchCriteriaBuilder->create();
return $this->entryRepositoryInterface->getList($searchCriteria)->getItems();
FYI, I've also created 2 dummy examples at the webroot folder on a default Magento sample data to prove it. See them here
I hope that it helps.
OTHER TIPS
Full working example based on other answer
use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Framework\Api\SortOrder;
use Magento\Framework\Api\SortOrderFactory;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Framework\App\Helper\Context;
use Xigen\Estimator\Api\Data\EntryInterface;
use Xigen\Estimator\Api\EntryRepositoryInterface;
/**
* @param \Magento\Framework\App\Helper\Context $context
* @param \Xigen\Estimator\Api\EntryRepositoryInterface $entryRepositoryInterface
* @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
* @param \Magento\Framework\Api\SortOrderFactory $sortOrderFactory
*/
public function __construct(
Context $context,
EntryRepositoryInterface $entryRepositoryInterface,
SearchCriteriaBuilder $searchCriteriaBuilder,
SortOrderFactory $sortOrderFactory
) {
$this->entryRepositoryInterface = $entryRepositoryInterface;
$this->sortOrderFactory = $sortOrderFactory;
$this->searchCriteriaBuilder = $searchCriteriaBuilder;
parent::__construct($context);
}
/**
* Get estimates
* @param country
* @return array
*/
public function getEstimates($country = null)
{
$this->searchCriteriaBuilder->addFilter(EntryInterface::STATUS, 1, 'eq');
if ($country) {
$this->searchCriteriaBuilder->addFilter(EntryInterface::COUNTRY, $country, 'eq');
}
$sortOne = $this->sortOrderFactory->create()
->setField(EntryInterface::COUNTRY)
->setDirection(SortOrder::SORT_ASC);
$sortTwo = $this->sortOrderFactory->create()
->setField(EntryInterface::SORT)
->setDirection(SortOrder::SORT_ASC);
$this->searchCriteriaBuilder->setSortOrders([$sortOne, $sortTwo]);
$searchCriteria = $this->searchCriteriaBuilder->create();
return $this->entryRepositoryInterface->getList($searchCriteria)->getItems();
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange