Filtering with custom attributes

As of 2.3.4, the filter attribute of the products query accepts the ProductAttributeFilterInput object. (In previous versions, the filter attribute required a ProductFilterInput object. This object contained a hardcoded list of filterable attributes, and you could not filter on a custom attribute or any other attribute that was not on the list.)

Prerequisites

You have several options when enabling a custom attribute (or any attribute that is not listed by default in the ProductAttributeFilterInput object) for filtering. Navigate to the attribute's Storefront Properties page (Stores > Attributes > Product > <attribute name> > Storefront Properties) in the Admin, then perform one or both of the following actions:

Define the filter for your query

The filter definition for your custom attribute requires one of the following input data types:

Example

In this example, the custom attribute volume was assigned to the bags attribute group. Running the customAttributeMetadata query on this custom attribute reveals that the label and value values for the attribute's options are as follows:

Request:

{
  customAttributeMetadata(
    attributes: [
      {
        attribute_code: "volume"
        entity_type: "catalog_product"
      }
    ]
  ) {
    items {
      attribute_code
      attribute_type
      entity_type
      input_type
      attribute_options {
       value
       label
     }
    }
  }
}

Response:

{
  "data": {
    "customAttributeMetadata": {
      "items": [
        {
          "attribute_code": "volume",
          "attribute_type": "Int",
          "entity_type": "catalog_product",
          "input_type": "select",
          "attribute_options": [
            {
              "value": "216",
              "label": "Large"
            },
            {
              "value": "217",
              "label": "Medium"
            },
            {
              "value": "218",
              "label": "Small"
            }
          ]
        }
      ]
    }
  }
}
label
value
Large
216
Medium
217
Small
218

In this scenario, a products search filtered to return items where the volume attribute is set to Large would be similar to the following:

Request:

{
  products(filter: { volume: { eq: "216" } }) {
    total_count
    items {
      name
      sku
    }
  }
}

Response:

The response might be similar to the following:

{
  "data": {
    "products": {
      "total_count": 1,
      "items": [
        {
          "name": "Wayfarer Messenger Bag",
          "sku": "24-MB05"
        }
      ]
    }
  }
}

Output attributes

When a product requires a filter attribute that is not a field on its output schema, inject the attribute name into the class in a module's di.xml file.

<type name="Magento\CatalogGraphQl\Model\Resolver\Products\FilterArgument\ProductEntityAttributesForAst" >
  <arguments>
    <argument name="additionalAttributes" xsi:type="array">
      <item name="field_to_sort" xsi:type="string">field</item>
      <item name="other_field_to_sort" xsi:type="string">other_field</item>
    </argument>
  </arguments>
</type>

This example adds field_to_sort and other_field_to_sort attributes to the additionalAttributes array defined in the ProductEntityAttributesForAst class. The array already contains the min_price, max_price, and category_uid attributes.