3

I am using Magento 2 Graphql to get product collection based on category id.

I want to apply filter by color, size, material etc.

I have checked the graphql available filters and those are not mentioned as input.

I am executing below query.

{
    products(
      filter:{category_id: {eq: "23"}, material: {eq: "cotton"}}
      currentPage: 1
      pageSize: 5
    ){
    items{
      name
    }
    total_count
  }
}

I have checked following file.

vendor/magento/module-catalog-graph-ql/etc/schema.graphqls

input ProductFilterInput @doc(description: "ProductFilterInput defines the filters to be used in the search. A filter contains at least one attribute, a comparison operator, and the value that is being searched for.") {
    name: FilterTypeInput @doc(description: "The product name. Customers use this name to identify the product.")
    sku: FilterTypeInput @doc(description: "A number or code assigned to a product to identify the product, options, price, and manufacturer")
    description: FilterTypeInput @doc(description: "Detailed information about the product. The value can include simple HTML tags.")
    short_description: FilterTypeInput @doc(description: "A short description of the product. Its use depends on the theme.")
    price: FilterTypeInput @doc(description: "The price of an item")
    special_price: FilterTypeInput @doc(description: "The discounted price of the product. Do not include the currency code.")
    special_from_date: FilterTypeInput @doc(description: "The beginning date that a product has a special price")
    special_to_date: FilterTypeInput @doc(description: "The end date that a product has a special price")
    weight: FilterTypeInput @doc(description: "The weight of the item, in units defined by the store")
    manufacturer: FilterTypeInput @doc(description: "A number representing the product's manufacturer")
    meta_title: FilterTypeInput @doc(description: "A string that is displayed in the title bar and tab of the browser and in search results lists")
    meta_keyword: FilterTypeInput @doc(description: "A comma-separated list of keywords that are visible only to search engines")
    meta_description: FilterTypeInput @doc(description: "A brief overview of the product for search results listings, maximum 255 characters")
    image: FilterTypeInput @doc(description: "The relative path to the main image on the product page")
    small_image: FilterTypeInput @doc(description: "The relative path to the small image, which is used on catalog pages")
    thumbnail: FilterTypeInput @doc(description: "The relative path to the product's thumbnail image")
    tier_price: FilterTypeInput @doc(description: "The price when tier pricing is in effect and the items purchased threshold has been reached")
    news_from_date: FilterTypeInput @doc(description: "The beginning date for new product listings, and determines if the product is featured as a new product")
    news_to_date: FilterTypeInput @doc(description: "The end date for new product listings")
    custom_layout_update: FilterTypeInput @doc(description: "XML code that is applied as a layout update to the product page")
    min_price: FilterTypeInput @doc(description:"The numeric minimal price of the product. Do not include the currency code.")
    max_price: FilterTypeInput @doc(description:"The numeric maximal price of the product. Do not include the currency code.")
    category_id: FilterTypeInput @doc(description: "Category ID the product belongs to")
    options_container: FilterTypeInput @doc(description: "If the product has multiple options, determines where they appear on the product page")
    required_options: FilterTypeInput @doc(description: "Indicates whether the product has required options")
    has_options: FilterTypeInput @doc(description: "Indicates whether additional attributes have been created for the product")
    image_label: FilterTypeInput @doc(description: "The label assigned to a product image")
    small_image_label: FilterTypeInput @doc(description: "The label assigned to a product's small image")
    thumbnail_label: FilterTypeInput @doc(description: "The label assigned to a product's thumbnail image")
    created_at: FilterTypeInput @doc(description: "Timestamp indicating when the product was created")
    updated_at: FilterTypeInput @doc(description: "Timestamp indicating when the product was updated")
    country_of_manufacture: FilterTypeInput @doc(description: "The product's country of origin")
    custom_layout: FilterTypeInput @doc(description: "The name of a custom layout")
    gift_message_available: FilterTypeInput @doc(description: "Indicates whether a gift message is available")
    or: ProductFilterInput @doc(description: "The keyword required to perform a logical OR comparison")
}

Here i am not able to see color, size, material etc. I added them using a custom extension but still, filtering with them, gives me 0 results.

Anyone having any idea about it ?

1

4 Answers 4

2

I Have done the same in my recent project.For this i created a custom module.

1.Create custom module.

2.Define the attributes in di.xml.

3.Add the attributes to ProductFilterInput.

4.Create the ProductAttributeFilter.php file in the relevant directory as defined in di.xml.

5.Run the graphql query to get the result.

My di.xml file looks like below

<?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>

Add the attributes to ProductFilterInput

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")
}

Create the ProductAttributeFilter.php file in the relevant directory as defined in di.xml.

<?php
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;
}
}

After this want to pass the added attribute to products graphQl query to get the result. I have written an article How to filter product collection with default graphql products query? Hope this will help you to build up your task.

My query and answer as images enter image description here

enter image description here

You may read more articles about create graphql module in magento 2 by visiting this.

3
  • Nope, it is not working for me. I implemented everything you have suggested still it shows 0 items if if filter by category_id and color.
    – Yash Shah
    Commented Dec 23, 2019 at 4:42
  • what do you get after adding only the catergory id?
    – Mujahidh
    Commented Dec 23, 2019 at 5:38
  • apply category_id and color filter onnly and check if you get configurable product in return or not
    – Yash Shah
    Commented Dec 26, 2019 at 4:49
1

In order to enable an attribute which is not listed by default for filtering, select the attribute on the Stores > Attributes > Product page in the Admin and edit the following fields:

  • Use in Search: Yes
  • Visible in Advanced Search: Yes
  • Use in Layered Navigation: Filterable (with results) or Filterable (no results)
  • Use in Search Results Layered Navigation: Yes
0

Try to upgrade the version. I had also facing that problem with v2.3.3 so I upgraded it to v2.3.6. I can also migrate to 2.4 but as elasticsearch is required in v2.4 so i just updated to v2.3.6 and it custom filters got working properly.

Steps to update

cp composer.json composer.json.bak
composer require magento/product-community-edition=2.3.6 --no-update
composer update
php bin/magento setup:upgrade
php bin/magento setup:static-content:deploy -f
chmod -R 777 var/ generated/ pub/
php bin/magento cache:clean
0

please follow this link if you want product collection using graphql

https://github.com/viveksh2021/GraphQL

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.