/   /   /  Magento 2 For developer : some ideas about Search Framwork

Note:

For more extensions and themes visit our store

Magento 2 For developer : some ideas about Search Framwork


The search use 3 request name in magento 2 :

'quick_search_container' when you search from the small field text in the top.

'advanced_search_container' when you use the advanced search page.

'catalog_view_container' when you entre to category page or use filter in category page it's work by default.

 

inside class Magento\Framework\Search\Search the function search(SearchCriteriaInterface $searchCriteria) build a request with class Magento\Framework\Search\Request\Builder; it's start by puching the query name to the object $this->requestBuilder  (example 'quick_search_container')

After that the scope pushed , it's get the current scope with $this->scopeResolver instance of class Magento\Framework\App\ScopeResolverInterface you can puch form (where start the search ('current page') and the page size) , after that it's use the $searchEngine instance of Magento\Framework\Search\SearchEngineInterface for cible the current or resource of search example solr or mysql :


  1. $searchResponse = $this->searchEngine->search($request);
  2.  

after that it use :

$this->searchResponseBuilder instance Of Magento\Framework\Search\SearchResponseBuilder

  1.  
  2. return $this->searchResponseBuilder->build($searchResponse)->setSearchCriteria($searchCriteria);
  3.  
  4.  

the complete function is :

  1.  
  2. public function search(SearchCriteriaInterface $searchCriteria){
  3. $this->requestBuilder->setRequestName($searchCriteria->getRequestName());
  4. $scope = $this->scopeResolver->getScope()->getId();
  5. $this->requestBuilder->bindDimension('scope', $scope);
  6. foreach ($searchCriteria->getFilterGroups() as $filterGroup) {
  7. foreach ($filterGroup->getFilters() as $filter) {
  8. $this->addFieldToFilter($filter->getField(), $filter->getValue());
  9. }
  10. }
  11. $this->requestBuilder->setFrom($searchCriteria->getCurrentPage() * $searchCriteria->getPageSize());
  12. $this->requestBuilder->setSize($searchCriteria->getPageSize());
  13. $request = $this->requestBuilder->create();
  14. $searchResponse = $this->searchEngine->search($request);
  15. return $this->searchResponseBuilder->build($searchResponse)->setSearchCriteria($searchCriteria);
  16. }
  17.  

don't forget that function manage the filter too with :

  1.  
  2. private function addFieldToFilter($field, $condition = null)
  3. {
  4. if (!is_array($condition) || !in_array(key($condition), ['from', 'to'], true)) {
  5. $this->requestBuilder->bind($field, $condition);
  6. } else {
  7. if (!empty($condition['from'])) {
  8. $this->requestBuilder->bind("{$field}.from", $condition['from']);
  9. }
  10. if (!empty($condition['to'])) {
  11. $this->requestBuilder->bind("{$field}.to", $condition['to']);
  12. }
  13. }
  14. return $this;
  15. }
  16.  

for analyse of form and add some condition field filter like price or date ,
where is catalog use this function :

vendor/magento/module-catalog-search/Model/ResourceModel/Fulltext/Collection.php
vendor/magento/module-catalog-search/Model/ResourceModel/Advanced/Collection.php

in protected function _renderFiltersBefore()

Compare 2 result of Aggregations :

category view container with 1 product result :

object(Magento\Framework\Search\Response\Aggregation)#1760 (1) { ["buckets":protected]=> array(4) { ["price_bucket"]=> object(Magento\Framework\Search\Response\Bucket)#1674 (2) { ["name":protected]=> string(12) "price_bucket" ["values":protected]=> array(1) { [0]=> object(Magento\Framework\Search\Response\Aggregation\Value)#1163 (2) { ["value":"Magento\Framework\Search\Response\Aggregation\Value":private]=> string(4) "10_*" ["metrics":"Magento\Framework\Search\Response\Aggregation\Value":private]=> array(2) { ["value"]=> string(4) "10_*" ["count"]=> string(1) "1" } } } } ["category_bucket"]=> object(Magento\Framework\Search\Response\Bucket)#1132 (2) { ["name":protected]=> string(15) "category_bucket" ["values":protected]=> array(0) { } } ["color_bucket"]=> object(Magento\Framework\Search\Response\Bucket)#1798 (2) { ["name":protected]=> string(12) "color_bucket" ["values":protected]=> array(0) { } } ["manufacturer_bucket"]=> object(Magento\Framework\Search\Response\Bucket)#1133 (2) { ["name":protected]=> string(19) "manufacturer_bucket" ["values":protected]=> array(0) { } } } }

category view container with 0 product result :

object(Magento\Framework\Search\Response\Aggregation)#1135 (1) { ["buckets":protected]=> array(4) { ["price_bucket"]=> object(Magento\Framework\Search\Response\Bucket)#1142 (2) { ["name":protected]=> string(12) "price_bucket" ["values":protected]=> array(0) { } } ["category_bucket"]=> object(Magento\Framework\Search\Response\Bucket)#1986 (2) { ["name":protected]=> string(15) "category_bucket" ["values":protected]=> array(0) { } } ["color_bucket"]=> object(Magento\Framework\Search\Response\Bucket)#1144 (2) { ["name":protected]=> string(12) "color_bucket" ["values":protected]=> array(0) { } } ["manufacturer_bucket"]=> object(Magento\Framework\Search\Response\Bucket)#2019 (2) { ["name":protected]=> string(19) "manufacturer_bucket" ["values":protected]=> array(0) { } } } }

 

Compare 2 result of Documents :

category view container with 1 product result :

array(1) { [0]=> object(Magento\Framework\Api\Search\Document)#1986 (1) { ["_data":protected]=> array(2) { ["id"]=> string(1) "1" ["custom_attributes"]=> array(1) { ["score"]=> object(Magento\Framework\Api\AttributeValue)#1161 (1) { ["_data":protected]=> array(2) { ["attribute_code"]=> string(5) "score" ["value"]=> string(18) "0.0000000000000000" } } } } } }

category view container with 0 product result :

array(0) { }

 

Document?

Most entities or objects in most applications can be serialized into a JSON object, with keys and values. A key is the name of a field or property, and a value can be a string, a number, a Boolean, another object, an array of values, or some other specialized type such as a string representing a date or an object representing a geolocation:

 

Buckets

A bucket is simply a collection of documents that meet certain criteria:

An employee would land in either the male or female bucket.

The city of Albany would land in the New York state bucket.

The date 2014-10-28 would land within the October bucket.

As aggregations are executed, the values inside each document are evaluated to determine whether they match a bucket’s criteria. If they match, the document is placed inside the bucket and the aggregation continues.

Buckets can also be nested inside other buckets, giving you a hierarchy or conditional partitioning scheme. For example, Cincinnati would be placed inside the Ohio state bucket, and the entire Ohio bucket would be placed inside the USA country bucket.

Elasticsearch has a variety of buckets, which allow you to partition documents in many ways (by hour, by most-popular terms, by age ranges, by geographical location, and more). But fundamentally they all operate on the same principle: partitioning documents based on criteria.

 

Aggregation

A multi-bucket value source based aggregation where buckets are dynamically built - one per unique value.

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-terms-aggregation.html

Comments

IBNAB is a company made of a group of professionals whose work is providing secure open source solutions. Our company strives for reaching magnificent results with each experience and provides professional open source solutions that cover every part of the business process.

Newsletter