Recently, one of our customers approached us with the following question:
I saw you can adjust priority on attributes, and on products. We have an attribute with a couple of properties. Is it possible to give more weight to a certain attribute value instead of a match on a whole attribute?
This is a great question. The module doesn’t support boosting products by single attribute values which would mean that products with a certain value would be ranked higher in the search results. You can of course boost products, but that solution is not as flexible and would mean a lot of manual work if hundreds of products have to be adjusted.
Use Events to Tweak Search Results
For cases like this, IntegerNet_Solr comes with built in custom events which can be used by other modules in form of observers, a common concept in Magento development. Using these events, merchants gain a lot of flexibility because they can modify the behavior of the Solr module while indexing or while searching (querying).
Back to our example. In order to achieve a flexible boost of products which have a certain attribute value, you can use the event “integernet_solr_product_collection_load_after“. This event provides the objects which can be retrieved, in this case only one:
- ‘collection’ – the product collection which will be used for indexing.
You can observe the module by adding the following part to the config.xml of any of your modules:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<global> <models> <integernet_solrobserver> <class>IntegerNet_SolrObserver_Model</class> </integernet_solrobserver> </models> <events> <integernet_solr_product_collection_load_after> <observers> <integernet_solrobserver> <type>singleton</type> <class>integernet_solrobserver/observer</class> <method>modifyProductBoost</method> </integernet_solrobserver> </observers> </integernet_solr_product_collection_load_after> </events> </global> |
Please adjust the names (namespace and module name) to your own. Just take care that you don’t modify the name of the event “integernet_solr_product_collection_load_after”.
You can then create an observer class and the corresponding method whose name is defined in the config.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
<?php class IntegerNet_SolrObserver_Model_Observer { /** * @param Varien_Event_Observer $observer * @event integernet_solr_product_collection_load_after */ public function modifyProductBoost(Varien_Event_Observer $observer) { /** @var Mage_Catalog_Model_Resource_Product_Collection $collection */ $collection = $observer->getCollection(); foreach($collection as $product) { Mage::log($product->debug()); } } } |
This will log the raw product data to the file var/log/system.log. An excerpt of the results:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
2016-06-01T18:49:34+00:00 DEBUG (7): Array ( [entity_id] => 396 [entity_type_id] => 4 [attribute_set_id] => 14 [type_id] => simple [sku] => hde006 [...] [solr_boost] => 2.0000 [color] => 17 [electronic_type] => 219 [status] => 1 [visibility] => 4 [solr_exclude] => 0 [is_salable] => 1 ) 2016-06-01T18:49:34+00:00 DEBUG (7): Array ( [entity_id] => 397 [entity_type_id] => 4 [attribute_set_id] => 14 [type_id] => simple [sku] => hde010 [...] [color] => 20 [electronic_type] => 181 [status] => 1 [visibility] => 4 ) |
Depending on any condition, we want to modify the attribute value “solr_boost” depending on another attribute. In our example, we want to duplicate the boost if the value of manufacturer is “Sony”. You can archive this with the following observer code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<?php class IntegerNet_SolrObserver_Model_Observer { const BOOSTED_ATTRIBUTE_CODE = 'manufacturer'; const BOOSTED_ATTRIBUTE_VALUE = 'Sony'; const BOOST_MULTIPLIER = 2; /** * @param Varien_Event_Observer $observer * @event integernet_solr_product_collection_load_after */ public function modifyProductBoost(Varien_Event_Observer $observer) { /** @var Mage_Catalog_Model_Resource_Product_Collection $collection */ $collection = $observer->getCollection(); foreach($collection as $product) { if ($product->getData(self::BOOSTED_ATTRIBUTE_CODE) == self::BOOSTED_ATTRIBUTE_VALUE) { $solrBoost = $product->getData('solr_boost'); if (!$solrBoost) { $solrBoost = 1; } $product->setData($solrBoost * self::BOOST_MULTIPLIER); } } } } |
You can download the working sample module here.
Full List of Events:
integernet_solr_get_product_data
Parameters:
- product: the Magento product object
- product_data: the data which is prepared for indexing in Solr. Can be modified.
Purpose:
Modify the data which goes to Solr directly. It could have been used for the example above as well.
integernet_solr_update_query_text
Parameters:
- tranport: a transport object which contains the query which is used for searching.
Purpose:
Modify the search word(s) with this event. For example, you can insert your own replacement functionality.
integernet_solr_before_search_request
Parameters:
- transport: a transport object which contains all parts of the search requests, for example search query or params
Purpose:
Have full control of the search request which goes to Solr with this event.
integernet_solr_after_search_request
Parameters:
- result: the full search result as it comes from Solr
Purpose:
Modify the search results here, i.e. apply your own sorting.
integernet_solr_product_collection_load_before
Parameters:
- collection: the product collection which is used for indexing
Purpose:
Modify the product collection before loading, for example by adding additional attributes or filters.
integernet_solr_product_collection_load_after
Parameters:
- collection: the product collection which is used for indexing
Purpose:
Modify the product collection after loading, for example in order to modify the product data, see example above.
integernet_solr_can_index_product
Parameters:
- product: the Magento product
Purpose:
Exclude products from being indexed here. Just set $product->setSolrExclude(true) to exclude a product from indexing.
The Benefit of Events
Even though the use case our customer asked about is not covered by our extension’s features, the effort to implement events pays off: they pave the way for easy and individual customizations of search results. It’s one of our goals to create an extension that can be managed without the need to develop on a code basis, on the other hand it’s also our goal to not bloat it with features used only by a minority. Sometimes it’s tricky to keep the golden mean. Events are a just the right means here.

Author: Andreas von Studnitz
Andreas von Studnitz is a Magento developer and one of the Managing Directors at integer_net. His main areas of interest are backend development, Magento consulting and giving developer trainings. He is a Magento 2 Certified Professional Developer Plus and holds several other Magento certifications for both Magento 1 and Magento 2. Andreas was selected as a Magento Master in 2019 and 2020.