1. Documentation for Developers

Set up search query field mapping

When you need exact phrase matching in GraphQL search queries on the Experience Edge (Preview) schema, use the SearchQueryFieldMapping feature to map tokenized fields to non-tokenized computed fields. This translation happens internally in the query-building code, before queries are sent to the Solr search provider.

By default, text fields in the Solr index are tokenized, a process that splits text into individual terms using whitespace and punctuation. For example, "New Site" becomes "new" and "site" separately. While this works for general text searches, it breaks exact phrase matching: a search query for _name == "Site" with the EQ operator behaves as CONTAINS, returning multiple results.

To resolve this, you can create a non-tokenized field (such as _customName) using a field type like lowercaseString that preserves the complete value as a single token, then map the original _name field to it during search operations. This enables exact matching while maintaining backward compatibility.

Before you begin

Make sure you have:

  • Access to your SitecoreAI environment.

  • Familiarity with SitecoreAI configuration files and deployment processes.

Configure search query field mapping

The following example demonstrates how to set up search query field mapping by mapping the _name field to a _customName computed field. For complete instructions on creating computed fields, see Creating a computed index field.

To configure the SearchQueryFieldMapping feature:

  1. Create a new computed index field

    Create a new computed field using the existing implementation Sitecore.Services.GraphQL.EdgeSchema.ComputedFields.CustomNameComputedField.

    Add new fields to the AddComputedIndexField node in the contentSearch section of your configuration file.

    This example creates the _customName field using the lowercaseString type:

    <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/"                xmlns:role="http://www.sitecore.net/xmlconfig/role/">
        <sitecore>
            <contentSearch>
                <indexConfigurations>
                    <defaultSolrIndexConfiguration>
                        <documentOptions type="Sitecore.ContentSearch.SolrProvider.SolrDocumentBuilderOptions, 
                                                Sitecore.ContentSearch.SolrProvider">
                            <fields hint="raw:AddComputedIndexField">
                                <!-- Create a non-tokenized version of the _name field -->
                                <field fieldName="_customName" 
                                       returnType="lowercaseString" 
                                       type="Sitecore.Services.GraphQL.EdgeSchema.ComputedFields.CustomNameComputedField, 
                                              Sitecore.Services.GraphQL.EdgeSchema" />
                            </fields>
                        </documentOptions>
                    </defaultSolrIndexConfiguration>
                </indexConfigurations>
            </contentSearch>
        </sitecore>
    </configuration>
  2. Map the search field name to the computed field

    To set up field mapping, add a field name mapping model to the setFieldMapping node. This model will be processed by the SearchQueryFieldMappingService when mapping a search query field.

    In the fieldMappingModel, map the _name field to the _customName field:

    <configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/">
        <sitecore>
            <api>
                <GraphQL>
                    <setFieldMapping 
                        type="Sitecore.Services.GraphQL.EdgeSchema.Services.SearchQueryFieldMapping.FieldMapping, 
                               Sitecore.Services.GraphQL.EdgeSchema">
                        <fieldMapping hint="list:AddFieldMapping">
                            <!-- Map the original _name field to the non-tokenized _customName field -->
                            <fieldMappingModel 
                                fieldName="_name" 
                                type="Sitecore.Services.GraphQL.EdgeSchema.Services.SearchQueryFieldMapping.FieldMappingModel, 
                                       Sitecore.Services.GraphQL.EdgeSchema">
                                <fieldName>_name</fieldName>
                                <mappingField>_customName</mappingField>
                            </fieldMappingModel>
                        </fieldMapping>
                    </setFieldMapping>
                </GraphQL>
            </api>
        </sitecore>
    </configuration>
  3. Include patches and deploy to Sitecore

    Commit your configuration patches from steps 1 and 2 to your project and deploy your SitecoreAI environment.

  4. Rebuild the index

    After deployment, rebuild the search index after making all the changes. After the index rebuild completes, the field mapping is active and ready to use.

Use the search query field mapping in queries

After configuration, for the Edge (Preview) schema, when you use the original field name (_name) in your GraphQL search queries, the mapping automatically redirects the query to use the non-tokenized field (_customName) internally in the Solr index. This means you continue using the original field name in your code while benefiting from exact matching behavior.

Example: Exact Match Query

When you use the EQ operator on the _name field, the search returns items matching the exact value. This query searches for "Sitecore Experience" and requests the id and name fields for each matching item:

query Search {
  search(
    where: {
      name: "_name"
      value: "Sitecore Experience"
      operator: EQ
    }
  ) {
    results {
      id
      name
    }
  }
}

Without the field mapping, this same query would return multiple results containing any of the tokenized terms. With the mapping to _customName, it returns only items where the name exactly matches "Sitecore Experience".

Example: Contains Query

The CONTAINS operator returns items that contain the search term, regardless of field mapping. This query searches for items containing "Sitecore" and requests the id and name fields:

query Search {
  search(
    where: {
      name: "_name"
      value: "Sitecore"
      operator: CONTAINS
    }
  ) {
    results {
      id
      name
    }
  }
}
Note

When configuring field mappings, consider the following:

  • The original field name (_name) remains usable in queries after mapping is configured.

  • Field mapping applies to the Preview endpoint only.

  • Multiple fields can be mapped to different non-tokenized versions.

  • Custom field names must be consistent between computed field definition and field mapping configuration.

If you have suggestions for improving this article, let us know!