Whats up mates welcome once more. On this weblog, we’ll take a look at how we are able to personalized type order in Elasticsearch by offering the type order within the array format.
Elasticsearch additionally offers a number of different sorting methods by default nonetheless this sorting approach is one in every of my favorites and has a number of use circumstances additionally.
To get began we first have to create a module during which we write our performance.
After creating the module we have to create a plugin to change the Elasticsearch question. For that, we first outline our plugin within the di.xml file at path app/code/VendorName/ModuleName/and many others/di.xml
<?xml model="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/and many others/config.xsd"> <kind identify="MagentoFrameworkSearchAdapterInterface"> <plugin identify="customize_elasticsearch_search_results" kind="WebkulCustomizeElasticsearchPluginElasticsearch7SearchAdapterAdapter" sortOrder="1" /> </kind> </config>
After defining the plugin we have to create our plugin file on the location outlined within the definition of the plugin.
<?php namespace WebkulCustomizeElasticsearchPluginElasticsearch7SearchAdapter; use MagentoFrameworkSearchRequestInterface; use MagentoElasticsearch7SearchAdapterMapper; use MagentoElasticsearchSearchAdapterResponseFactory; use MagentoElasticsearchSearchAdapterConnectionManager; use MagentoElasticsearchSearchAdapterQueryContainerFactory; use MagentoElasticsearchSearchAdapterAggregationBuilder as AggregationBuilder; class Adapter { /** * @var array */ personal static $emptyRawResponse = [ "hits" => [ "hits" => [] ], "aggregations" => [ "price_bucket" => [], "category_bucket" => [ "buckets" => [] ] ] ]; /** * Dependency Initilization * * @param Mapper $mapper * @param PsrLogLoggerInterface $logger * @param ResponseFactory $responseFactory * @param ConnectionManager $connectionManager * @param AggregationBuilder $aggregationBuilder * @param QueryContainerFactory $queryContainerFactory * @param MagentoFrameworkMessageManagerInterface $messageManager * @param MagentoCatalogModelResourceModelProductCollectionFactory $collectionFactory */ public operate __construct( personal Mapper $mapper, personal PsrLogLoggerInterface $logger, personal ResponseFactory $responseFactory, personal ConnectionManager $connectionManager, personal AggregationBuilder $aggregationBuilder, personal QueryContainerFactory $queryContainerFactory, personal MagentoFrameworkMessageManagerInterface $messageManager, personal MagentoCatalogModelResourceModelProductCollectionFactory $collectionFactory ) { } /** * Add vendor product to vendor assortment * * @param MagentoFrameworkSearchAdapterInterface $topic * @param callable $proceed * @param RequestInterface $request */ public operate aroundQuery( MagentoFrameworkSearchAdapterInterface $topic, callable $proceed, RequestInterface $request ) { attempt { $productIds = $this->getProductCustomSortOrder(); $consumer = $this->connectionManager->getConnection(); $aggregationBuilder = $this->aggregationBuilder; $updatedQuery = $this->mapper->buildQuery($request); unset($updatedQuery['body']['query']['bool']['should']); unset($updatedQuery['body']['query']['bool']['minimum_should_match']); unset($updatedQuery['body']['sort']); $updatedQuery['body']['sort'][0]['_script']['type'] = 'quantity'; $setSortOrderAttribute = 'params.sortOrder.indexOf(doc["_id"].worth)'; $updatedQuery['body']['sort'][0]['_script']['script']['inline'] = $setSortOrderAttribute; $updatedQuery['body']['sort'][0]['_script']['script']['params']['sortOrder'] = $productIds; unset($updatedQuery['body']['sort'][0]['_score']); $updatedQuery['body']['query']['bool']['filter'] = ['ids' => ['values' => $productIds]]; $aggregationBuilder->setQuery($this->queryContainerFactory->create(['query' => $updatedQuery])); attempt { $rawResponse = $client->question($updatedQuery); } catch (Exception $e) { $this->logger->debug( "Elasticsearch7_SearchAdapter_Adapter aroundQuery " . $e->getMessage() ); $rawResponse = self::$emptyRawResponse; } $rawDocuments = $rawResponse['hits']['hits'] ?? []; $queryResponse = $this->responseFactory->create( [ 'documents' => $rawDocuments, 'aggregations' => $aggregationBuilder->build($request, $rawResponse), 'total' => $rawResponse['hits']['total']['value'] ?? 0 ] ); return $queryResponse; } catch (Exception $e) { $this->logger->debug( "Elasticsearch7_SearchAdapter_Adapter aroundQuery " . $e->getMessage() ); $this->messageManager->addError(__($e->getMessage())); } return $proceed($request); } /** * Get Product Customized SortOrder * * @return array */ personal operate getProductCustomSortOrder() { $merchandise = $this->collectionFactory->create() ->addFieldToFilter('visibility', ['in' => [3, 4]]); $evenProductIds = []; $oddProductIds = []; foreach ($merchandise as $product) { if ($product->getEntityId() % 2 == 0) { $evenProductIds[] = $product->getEntityId(); } else { $oddProductIds[] = $product->getEntityId(); } } return array_merge($oddProductIds, $evenProductIds); } }
The code that really helps in sorting is.
$updatedQuery['body']['sort'][0]['_script']['type'] = 'quantity'; $setSortOrderAttribute = 'params.sortOrder.indexOf(doc["_id"].worth)'; $updatedQuery['body']['sort'][0]['_script']['script']['inline'] = $setSortOrderAttribute; $updatedQuery['body']['sort'][0]['_script']['script']['params']['sortOrder'] = $productIds;
Our precise question format appears to be like one thing like this.
Array ( [body] => Array ( [sort] => Array ( [0] => Array ( [_script] => Array ( [type] => quantity [script] => Array ( [inline] => params.sortOrder.indexOf(doc["_id"].worth) [params] => Array ( [sortOrder] => Array ( [0] => 1 [1] => 3 [2] => 5 [3] => 7 [4] => 9 [5] => 2 [6] => 4 [7] => 6 [8] => 8 [9] => 10 ) ) ) ) ) ) ) )
Right here our sortOrder array incorporates all of the odd product IDs first and all of the even product IDs after them which causes our product itemizing to type merchandise in that method.
In keeping with the above code, our product itemizing might be.
That’s all guys we now have efficiently personalized type order for our product itemizing.
Whats up mates welcome once more. On this weblog, we’ll take a look at how we are able to personalized type order in Elasticsearch by offering the type order within the array format.
Elasticsearch additionally offers a number of different sorting methods by default nonetheless this sorting approach is one in every of my favorites and has a number of use circumstances additionally.
To get began we first have to create a module during which we write our performance.
After creating the module we have to create a plugin to change the Elasticsearch question. For that, we first outline our plugin within the di.xml file at path app/code/VendorName/ModuleName/and many others/di.xml
<?xml model="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/and many others/config.xsd"> <kind identify="MagentoFrameworkSearchAdapterInterface"> <plugin identify="customize_elasticsearch_search_results" kind="WebkulCustomizeElasticsearchPluginElasticsearch7SearchAdapterAdapter" sortOrder="1" /> </kind> </config>
After defining the plugin we have to create our plugin file on the location outlined within the definition of the plugin.
<?php namespace WebkulCustomizeElasticsearchPluginElasticsearch7SearchAdapter; use MagentoFrameworkSearchRequestInterface; use MagentoElasticsearch7SearchAdapterMapper; use MagentoElasticsearchSearchAdapterResponseFactory; use MagentoElasticsearchSearchAdapterConnectionManager; use MagentoElasticsearchSearchAdapterQueryContainerFactory; use MagentoElasticsearchSearchAdapterAggregationBuilder as AggregationBuilder; class Adapter { /** * @var array */ personal static $emptyRawResponse = [ "hits" => [ "hits" => [] ], "aggregations" => [ "price_bucket" => [], "category_bucket" => [ "buckets" => [] ] ] ]; /** * Dependency Initilization * * @param Mapper $mapper * @param PsrLogLoggerInterface $logger * @param ResponseFactory $responseFactory * @param ConnectionManager $connectionManager * @param AggregationBuilder $aggregationBuilder * @param QueryContainerFactory $queryContainerFactory * @param MagentoFrameworkMessageManagerInterface $messageManager * @param MagentoCatalogModelResourceModelProductCollectionFactory $collectionFactory */ public operate __construct( personal Mapper $mapper, personal PsrLogLoggerInterface $logger, personal ResponseFactory $responseFactory, personal ConnectionManager $connectionManager, personal AggregationBuilder $aggregationBuilder, personal QueryContainerFactory $queryContainerFactory, personal MagentoFrameworkMessageManagerInterface $messageManager, personal MagentoCatalogModelResourceModelProductCollectionFactory $collectionFactory ) { } /** * Add vendor product to vendor assortment * * @param MagentoFrameworkSearchAdapterInterface $topic * @param callable $proceed * @param RequestInterface $request */ public operate aroundQuery( MagentoFrameworkSearchAdapterInterface $topic, callable $proceed, RequestInterface $request ) { attempt { $productIds = $this->getProductCustomSortOrder(); $consumer = $this->connectionManager->getConnection(); $aggregationBuilder = $this->aggregationBuilder; $updatedQuery = $this->mapper->buildQuery($request); unset($updatedQuery['body']['query']['bool']['should']); unset($updatedQuery['body']['query']['bool']['minimum_should_match']); unset($updatedQuery['body']['sort']); $updatedQuery['body']['sort'][0]['_script']['type'] = 'quantity'; $setSortOrderAttribute = 'params.sortOrder.indexOf(doc["_id"].worth)'; $updatedQuery['body']['sort'][0]['_script']['script']['inline'] = $setSortOrderAttribute; $updatedQuery['body']['sort'][0]['_script']['script']['params']['sortOrder'] = $productIds; unset($updatedQuery['body']['sort'][0]['_score']); $updatedQuery['body']['query']['bool']['filter'] = ['ids' => ['values' => $productIds]]; $aggregationBuilder->setQuery($this->queryContainerFactory->create(['query' => $updatedQuery])); attempt { $rawResponse = $client->question($updatedQuery); } catch (Exception $e) { $this->logger->debug( "Elasticsearch7_SearchAdapter_Adapter aroundQuery " . $e->getMessage() ); $rawResponse = self::$emptyRawResponse; } $rawDocuments = $rawResponse['hits']['hits'] ?? []; $queryResponse = $this->responseFactory->create( [ 'documents' => $rawDocuments, 'aggregations' => $aggregationBuilder->build($request, $rawResponse), 'total' => $rawResponse['hits']['total']['value'] ?? 0 ] ); return $queryResponse; } catch (Exception $e) { $this->logger->debug( "Elasticsearch7_SearchAdapter_Adapter aroundQuery " . $e->getMessage() ); $this->messageManager->addError(__($e->getMessage())); } return $proceed($request); } /** * Get Product Customized SortOrder * * @return array */ personal operate getProductCustomSortOrder() { $merchandise = $this->collectionFactory->create() ->addFieldToFilter('visibility', ['in' => [3, 4]]); $evenProductIds = []; $oddProductIds = []; foreach ($merchandise as $product) { if ($product->getEntityId() % 2 == 0) { $evenProductIds[] = $product->getEntityId(); } else { $oddProductIds[] = $product->getEntityId(); } } return array_merge($oddProductIds, $evenProductIds); } }
The code that really helps in sorting is.
$updatedQuery['body']['sort'][0]['_script']['type'] = 'quantity'; $setSortOrderAttribute = 'params.sortOrder.indexOf(doc["_id"].worth)'; $updatedQuery['body']['sort'][0]['_script']['script']['inline'] = $setSortOrderAttribute; $updatedQuery['body']['sort'][0]['_script']['script']['params']['sortOrder'] = $productIds;
Our precise question format appears to be like one thing like this.
Array ( [body] => Array ( [sort] => Array ( [0] => Array ( [_script] => Array ( [type] => quantity [script] => Array ( [inline] => params.sortOrder.indexOf(doc["_id"].worth) [params] => Array ( [sortOrder] => Array ( [0] => 1 [1] => 3 [2] => 5 [3] => 7 [4] => 9 [5] => 2 [6] => 4 [7] => 6 [8] => 8 [9] => 10 ) ) ) ) ) ) ) )
Right here our sortOrder array incorporates all of the odd product IDs first and all of the even product IDs after them which causes our product itemizing to type merchandise in that method.
In keeping with the above code, our product itemizing might be.
That’s all guys we now have efficiently personalized type order for our product itemizing.