How to filter product collection with default GraphQl products query in Magento 2? – This topic is very important when it comes to the layered navigation. Normally we need to filter our product collection with custom product attributes and default product attributes.
The native GraphQl products query not include color, size, and custom attributes. So today we are going to see how we can get this done by the use of a custom module.
You can view all my Magento 2 GraphQL tutorials below.
- What is GraphQl in Magento 2 and how to access it?
- How to create GraphQl schema for Magento 2 custom module with custom table?
- How to create a GraphQl schema by passing argument for custom magento 2 module with custom table ?
- How to write GrapgQl mutation to create and integrate the contact us page functionality in Magento 2?
- How to filter product collection with default GraphQl products query in Magento 2?
- How to write custom search using GraphQl in Magento 2?
- How to get the store configuration values using GraphQl in magento 2?
Custom Module’s Structure.

module.xml file
1 2 3 4 5 6 7 8 9 |
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Ayakil_CatalogGraphQl" setup_version="1.0.5"> <sequence> <module name="Magento_CatalogGraphQl"/> </sequence> </module> </config> |
We want to define, undefined(in Native GraphQl) products attribute in the di.xml(Ayakil\CatalogGraphQl\ figraphql\di.xml) file first. As well as our custom product attributes too. This module I will handle color, size(default attribute), region, language(custom Attribute).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?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="Magento\Catalog\Model\Api\SearchCriteria\CollectionProcessor\ProductFilterProcessor" type="Magento\Eav\Model\Api\SearchCriteria\CollectionProcessor\FilterProcessor"> <arguments> <argument name="customFilters" xsi:type="array"> <item name="color" xsi:type="object"> Ayakil\CatalogGraphQl\Model\Resolver\Products\SearchCriteria\CollectionProcessor\FilterProcessor\ProductAttributeFilter </item> <item name="size" xsi:type="object"> Ayakil\CatalogGraphQl\Model\Resolver\Products\SearchCriteria\CollectionProcessor\FilterProcessor\ProductAttributeFilter </item> <item name="region" xsi:type="object"> Ayakil\CatalogGraphQl\Model\Resolver\Products\SearchCriteria\CollectionProcessor\FilterProcessor\ProductAttributeFilter </item> <item name="language" xsi:type="object"> Ayakil\CatalogGraphQl\Model\Resolver\Products\SearchCriteria\CollectionProcessor\FilterProcessor\ProductAttributeFilter </item> </argument> </arguments> </virtualType> </config> |
After this, we want to define the custom attribute and native product attribute as FilterTypeInput to ProductFilterInput in the schema.graphqls file like below.
1 2 3 4 5 6 7 8 9 10 |
input ProductFilterInput { category_url_key: FilterTypeInput @doc(description: "Category url_key the product belongs to") category_url_path: FilterTypeInput @doc(description: "Category url_path the product belongs to") color: FilterTypeInput @doc(description: "Product color") size: FilterTypeInput @doc(description: "Product size") region: FilterTypeInput @doc(description: "Product Region") language: FilterTypeInput @doc(description: "Product Language") url_key: FilterTypeInput @doc(description: "Product url") } |
After this, we want to create ProductAttributeFilter.php file under the Model directory. As we defined in the di.xml file(path is Ayakil\CatalogGraphQl\Model\Resolver\Products\SearchCriteria\CollectionProcessor\FilterProcessor\). I followed the default Magento’s module-catlog-graph-ql module to achieve this task.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 |
<?php /** * Ayakil_CatalogGraphQl * * @category Ayakil * @package Ayakil_CatalogGraphQl */ declare(strict_types=1); namespace Ayakil\CatalogGraphQl\Model\Resolver\Products\SearchCriteria\CollectionProcessor\FilterProcessor; use Magento\Catalog\Model\Product\Attribute\Source\Status; use Magento\Framework\Api\SearchCriteria\CollectionProcessor\FilterProcessor\CustomFilterInterface; use Magento\Framework\Data\Collection\AbstractDb; use Magento\Framework\Api\Filter; use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory; use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable; use Magento\Framework\Registry; /** * Category filter allows to filter products collection using custom defined filters from search criteria. */ class ProductAttributeFilter implements CustomFilterInterface { protected $configurable; protected $collectionFactory; protected $registry; public function __construct( Configurable $configurable, CollectionFactory $collectionFactory, \Psr\Log\LoggerInterface $logger, Registry $registry ) { $this->registry = $registry; $this->configurable = $configurable; $this->logger = $logger; $this->collectionFactory = $collectionFactory; } public function apply(Filter $filter, AbstractDb $collection) { $conditionType = $filter->getConditionType(); $attributeName = $filter->getField(); $attributeValue = $filter->getValue(); $category = $this->registry->registry('current_category'); if($attributeName == 'language'){ $conditions = []; foreach ($attributeValue as $value){ $conditions[] = ['attribute'=>$attributeName, 'finset'=>$value]; } $simpleSelect = $this->collectionFactory->create() ->addAttributeToFilter($conditions); }else{ $simpleSelect = $this->collectionFactory->create() ->addAttributeToFilter($attributeName, [$conditionType => $attributeValue]); } $simpleSelect->addAttributeToFilter('status', Status::STATUS_ENABLED); if ($category) { $simpleSelect->addCategoriesFilter(['in' => (int)$category->getId()]); } $arr = $simpleSelect; $entity_ids = []; foreach ($arr->getData() as $a){ $entity_ids[] = $a['entity_id']; } $collection->getSelect()->where($collection->getConnection()->prepareSqlCondition( 'e.entity_id', ['in' => $entity_ids] )); return true; } } |
This will help you to filter the product collection with product attributes that are not defined in native products GraphQl. So we can use the default products GraphQl query to get the result. Below is the GrapQl query which I am passing with the custom attributes to get the collection.
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
query { products(filter: { category_id:{eq: "58"} region: {in: [ "277"]} language: {in: ["304"]} price: {eq: "75"} color:{eq: "49"} } pageSize: 20 currentPage: 1 sort: { price: DESC } ) { filters { name filter_items_count request_var filter_items { label value_string } } items { id name sku type_id short_description { html } price { regularPrice { amount { value currency } } } } total_count page_info { page_size } } } |

In this query, I have passed the region, language, color as filters to the native products GrapQl query to get the results. Below is the sample result I have received from the query.

That’s it for today’s article. The summery for the entire article is
- Create custom module.
- Define the attributes in di.xml.
- Add the attributes to ProductFilterInput.
- Create the ProductAttributeFilter.php file in the relevant directory as defined in di.xml.
- Run the graphql query to get the result.
Always welcome the corrections, suggestions, and improvements to my blog. You can read my previous articles here.
Have a nice day. Enjoy coding, Learn, Experience, Teach, and Help.
I’m unable to run graphql after deploying my code which was most similar to your usecase.
Can you share your module please.
thanks for reading, I sent the module.
Hi Mujahidh,
I am facing some issues, can you please send me your module ?
I sent you. Please check
Hello Mujahidh.
can you send me module too?
This is awesome, but not working for me.
Thanks.
Dear Xin Li,
Thank you for reading my blog.
I will send you the module to your email.
Thanks, I’ve received.
Is this working one for m2.3.4?