How to cache Magento collection query results

How to cache Magento collection query results

Introduction

Today, I would like to introduce “How to cache the Magento collection result” without customizing the PHP code. When you have worked with the Magento collection, you would like to consider if you can cache the result for the next time if the data aren’t generally updated by admin or 3rd tools. By default, Magento support saves the result of the collection to cache but it is not enabled by default, we have to add some custom to di.xml to active the feature. And here are detailed steps.

I have an example for this case:

  • I want to load a list of banners from the homepage, as you know the banner slider collection is not generally updated. Thus, I created a block that is used for getting banner collection

BannerSlider.php

<?php /** * Copyright © MagEx Digital All rights reserved. * See COPYING.txt for license details. */ declare(strict_types=1); namespace MagEx\BannerSlider\Block\Widget; use Magento\Framework\View\Element\Template; use Magento\Widget\Block\BlockInterface; use MagEx\BannerSlider\Model\ResourceModel\Slider\CollectionFactory; class BannerSlider extends Template implements BlockInterface { protected $_sliderCollectionFactory; public function __construct( Template\Context $context, CollectionFactory $sliderCollectionFactory, array $data = []) { parent::__construct($context, $data); $this->_sliderCollectionFactory = $sliderCollectionFactory; } public function getSliderCollection(){ return $this->_sliderCollectionFactory->create(); } }
Code language: HTML, XML (xml)

As you can see, I just have created a widget that loads the slider collection without implementing the cache, now I will introduce you to how to cache the $sliderCollection without modifying the class Widget\BannerSlider

Create a dependency injection file: di.xml

Absolutely, you have to create a di.xml file for updating the class constructor parameters. Creating a di.xml under module_folder/etc/di.xml with sample code below

<?xml version="1.0" ?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <!-- Sample di.xml file --> </config>
Code language: HTML, XML (xml)

The $fetchStrategy

As I mentioned above that Magento supports cache the result of collection by default, now you can check the $fetchStategy on \Magento\Framework\Data\Collection\AbstractDb (file: vendor/magento/framework/Data/Collection/AbstractDb.php).

CacheFetchStrategy

By default the interface FetchStrategyInterface is preferenced by Magento\Framework\Data\Collection\Db\FetchStrategy\Query, Therefore we have to update the Slider\Collection to use the CacheStrategy instead for activating the cache. I will add those line to the di.xml

<?xml version="1.0" ?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="MagEx\BannerSlider\Model\ResourceModel\Slider\Collection"> <arguments> <argument name="fetchStrategy" xsi:type="object">Magento\Framework\Data\Collection\Db\FetchStrategy\Cache</argument> </arguments> </type> </config>
Code language: HTML, XML (xml)

The cache tags

Cleaning the cache, congratulation you have enabled the cache for Slider\Collection. But, what about if you want to clean the collection cache by tags? because the default stores the cache with the tag COLLECTION_DATA. If you want to adding some custom tags here is a sample

<?xml version="1.0" ?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <virtualType name="SliderCollectionCacheFetchStrategy" type="Magento\Framework\Data\Collection\Db\FetchStrategy\Cache"> <arguments> <argument name="cacheTags" xsi:type="array"> <item name="slider" xsi:type="string">banner_slider_collection</item> </argument> </arguments> </virtualType> <type name="MagEx\BannerSlider\Model\ResourceModel\Slider\Collection"> <arguments> <argument name="fetchStrategy" xsi:type="object">SliderCollectionCacheFetchStrategy</argument> </arguments> </type> </config>
Code language: HTML, XML (xml)

Enable cache for special class

After all, you have enabled the cache for Banner\Slider\Collection but it enables global scope, every class that requires Banner\Slider\Collection will have cache and UiComponent is included. Absolutly, we don’t want to the UiComponent use the cache. Thus, we have to create a virual class for the collection. And here is a sample on enable caching for the Banner\Slider\Collection on BannerSlider. Updates the di.xml.

<?xml version="1.0" ?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <virtualType name="SliderCollectionCacheFetchStrategy" type="Magento\Framework\Data\Collection\Db\FetchStrategy\Cache"> <arguments> <argument name="cacheTags" xsi:type="array"> <item name="slider" xsi:type="string">banner_slider_collection</item> </argument> </arguments> </virtualType> <virtualType name="VirtualBannerSliderCollection" type="MagEx\BannerSlider\Model\ResourceModel\Slider\Collection"> <arguments> <argument name="fetchStrategy" xsi:type="object">SliderCollectionCacheFetchStrategy</argument> </arguments> </virtualType> <virtualType name="VirtualTypeBannerSliderCollectionFactory" type="MagEx\BannerSlider\Model\ResourceModel\Slider\CollectionFactory"> <arguments> <argument name="instanceName" xsi:type="string">VirtualBannerSliderCollection</argument> </arguments> </virtualType> <type name="\MagEx\BannerSlider\Block\Widget\BannerSlider"> <arguments> <argument name="sliderCollectionFactory" xsi:type="object">VirtualTypeBannerSliderCollectionFactory</argument> </arguments> </type> </config>
Code language: HTML, XML (xml)

That’s all, you have enabled the cache for the Banner\Slider\Collection of the class Widget\BannerSlider thanks for reading my blog.

8 thoughts on “How to cache Magento collection query results

Average
5 Based On 8

Leave a Reply

Your email address will not be published. Required fields are marked *