How to Enable 'eq' Filter GraphQL Search for an Custom Attribute of Type Text in Magento 2

Generally there are 3 types of filter that you can use with graphql search and these filter type depends upon your attribute configuration.

  • FilterEqualTypeInput - Input type is set to Yes/No, Select, or Multiple select. Your filter can contain the eq or in attribute. Use the eq attribute to exactly match the specified string. Use the in attribute to filter on a comma-separated list of values.
  • FilterMatchTypeInput - Input type is set to Text Field or Text Area. Your filter must contain the match attribute, which will return all items that partially fuzzy match the specified string.
  • FilterRangeTypeInput - Input type is set to Price or Date. Your filter can contain one or both of the to and from attributes, which serve to provide a range of values to filter on.

If, for any reason, you require the text attribute to support the "eq" filter, you can follow the steps below:

Text attributes are using match attributes OOTB. But Magento leaves open door to change this behavior by injecting the custom attribute using the below classes. This behaviour we can see for sku,url_key etc.

  • Magento\CatalogGraphQl\Model\Config\FilterAttributeReader - inject style_code to private $exactMatchAttributes = ['sku']; allows to change graphQL queries to use eq attribute
  • Magento\CatalogGraphQl\Plugin\Search\Request\ConfigReader - inject style_code to “exactMatchAttribute“ change request guery for Elasticsearch.
Changel Graphql query to use eq filter

Update the di.xml file to inject the custom attribute to the variable exactMatchAttributes to the class Magento\CatalogGraphQl\Model\Config\FilterAttributeReader

<type name="Magento\CatalogGraphQl\Model\Config\FilterAttributeReader">
    <arguments>
        <argument name="exactMatchAttributes" xsi:type="array">
            <item name="custom_attribute" xsi:type="string">style_code</item>
        </argument>
    </arguments>
</type>
Change request query for Elasticsearch

Update the di.xml file to inject the custom attribute to the variable exactMatchAttributes in the class Magento\CatalogGraphQl\Plugin\Search\Request\ConfigReader

<type name="Magento\CatalogGraphQl\Plugin\Search\Request\ConfigReader">
    <arguments>
         <argument name="exactMatchAttributes" xsi:type="array">
                <item name="style_code" xsi:type="string">style_code</item>
         </argument>
    </arguments>
</type>

Verify Elasticsearch Keyword mapping

If an attribute needs to be searched with eq filter the attribute should have the keyword index mapping in the ElasticSearch.

This can be vieified iwth the below curl comand

curl --location --request GET 'http://localhost:9200/*/_mapping/field/url_key'
{
  "mappings": {
    "url_key": {
      "full_name": "url_key",
      "mapping": {
        "url_key": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword"
            }
          },
          "copy_to": [
            "_search"
          ]
        }
      }
    }
  }
}

Generally for all the attributes where the backend_type is "text", The keword mapping would not be set by default.

Here the attribute "test_text" will not have a keword mapping in elasticsearch so we cannot use "eq" filter.

To know more preciesly on where keword mapping will not be added refer the below file.

\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\StaticField::getField

But you can still make this type of attribute to support keyword mapping by updating the attribute index mapping. The index mapping for an attribute this set in the below method. So we can crete the afterPlugin for this method and have the mapping updated.

\Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\StaticField::getFields

Leave a Reply

Your email address will not be published.