In Elasticsearch, choosing between text and keyword fields directly affects how WooCommerce product data is searched, filtered, sorted, and aggregated. The distinction is especially important for agencies building catalog search, layered navigation, reporting, and integrations that synchronize products from WordPress and WooCommerce.
What is a text field?
A text field is designed for full-text search. Elasticsearch analyzes the value when it indexes the document. Analysis commonly includes tokenization, lowercasing, stemming, stop-word removal, or other language-specific processing.
For example, a WooCommerce product title such as Organic Cotton Running Shirt might be indexed as separate terms such as organic, cotton, running, and shirt. A search for cotton shirt can then match the product even though the query does not exactly reproduce the stored title.
{
"product_name": {
"type": "text"
}
}
Text fields are appropriate for values that customers read and search as language, including:
- Product names
- Long descriptions
- Short descriptions
- Searchable brand or collection descriptions
- Support and documentation content associated with products
What is a keyword field?
A keyword field stores a value as one exact, unanalyzed term. Elasticsearch does not split the value into words for standard full-text matching. This makes keyword fields suitable for exact filters, sorting, grouping, and aggregations.
For example, a WooCommerce SKU such as TSHIRT-BLU-M should normally remain one exact value. The same applies to an external product identifier, an order status, a stock status, or a controlled attribute value.
{
"sku": {
"type": "keyword"
},
"stock_status": {
"type": "keyword"
}
}
Keyword fields are appropriate for values such as:
- SKUs and variation SKUs
- WooCommerce product IDs and variation IDs
- Brand slugs and category slugs
- Stock statuses such as
instockandoutofstock - Taxonomy term IDs
- Color, size, material, and other controlled attribute values
- External marketplace or ERP identifiers
Text and keyword fields in the same mapping
Many product fields need both full-text search and exact operations. Elasticsearch supports this with a multi-field mapping. The main field is mapped as text, while a .keyword subfield stores the complete original value.
{
"mappings": {
"properties": {
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"brand": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"sku": {
"type": "keyword"
}
}
}
}
With this mapping, name can be queried as analyzed text, while name.keyword can be used for exact matching, sorting, or aggregations. For example, an agency might use name in a product search query and brand.keyword to build a brand aggregation.
Query behavior in a WooCommerce catalog
Use a match query against a text field when the customer is searching for words or phrases rather than an exact stored value.
{
"query": {
"match": {
"name": "waterproof hiking jacket"
}
}
}
Use a term query against a keyword field when the value must match exactly. This is useful for filters generated by WooCommerce attributes or product metadata.
{
"query": {
"term": {
"stock_status": "instock"
}
}
}
A common product search combines both behaviors. The customer-facing phrase can search analyzed fields, while filters use keyword fields:
{
"query": {
"bool": {
"must": [
{
"multi_match": {
"query": "running shoes",
"fields": ["name^3", "short_description", "description"]
}
}
],
"filter": [
{
"term": {
"stock_status": "instock"
}
},
{
"term": {
"attributes.color.keyword": "black"
}
}
]
}
}
}
Using filters for exact catalog constraints avoids affecting relevance scoring and is generally more efficient than placing the same conditions in the scored portion of the query.
SKUs require special handling
SKUs are usually best mapped as keyword because an SKU represents an identifier, not natural language. A term query is appropriate when looking up an exact SKU.
{
"query": {
"term": {
"sku": "TSHIRT-BLU-M"
}
}
}
If the storefront must support partial SKU searches, do not solve the problem by changing the SKU field to ordinary text without testing the analyzer. Hyphens, underscores, and numeric segments may be tokenized in ways that produce unexpected matches. Depending on the requirement, consider a dedicated autocomplete field, an edge-ngram analyzer, a prefix query, or a separate normalized search field.
WooCommerce attributes and taxonomy values
WooCommerce attributes can contain both human-readable labels and machine-oriented slugs. Agencies should decide which representation is needed for each use case.
- Index the attribute label as
textwhen it should participate in natural-language search. - Index the attribute slug or term ID as
keywordfor stable filtering. - Use keyword values for aggregations that populate layered navigation.
- Preserve the display label separately when the frontend must show localized filter names.
For example, a color attribute might be represented as Black for display and black as a stable filter value. Filtering on the slug avoids problems caused by capitalization, translated labels, or changes to the visible term name.
Case sensitivity and normalization
Keyword fields are exact by default, so Black and black are different values. For identifiers and filter values, define a normalizer when case-insensitive matching is required.
{
"settings": {
"analysis": {
"normalizer": {
"lowercase_normalizer": {
"type": "custom",
"filter": ["lowercase"]
}
}
}
},
"mappings": {
"properties": {
"brand_slug": {
"type": "keyword",
"normalizer": "lowercase_normalizer"
}
}
}
}
Normalizers operate on keyword values without tokenizing them. This is useful for case-insensitive SKU lookups, brand slugs, email addresses, and external IDs, provided that the business rules allow case normalization.
Sorting and aggregations
Sorting and aggregations normally require a keyword field or a numeric field. A plain text field cannot be used for these operations unless fielddata is explicitly enabled, which is usually an unnecessary memory cost for WooCommerce catalog data.
{
"sort": [
{
"name.keyword": "asc"
}
],
"aggs": {
"brands": {
"terms": {
"field": "brand.keyword"
}
}
}
}
For product prices, stock quantities, ratings, and dates, use numeric or date field types rather than keyword strings. A price stored as keyword may display correctly but cannot support reliable numeric sorting, ranges, or price aggregations.
Mapping decisions during index design
WooCommerce agencies should define mappings before indexing a production catalog. Dynamic mapping can infer types incorrectly, particularly when product metadata contains inconsistent values across products. A field that is first indexed as text cannot later be changed to keyword in place; the index must be recreated and the catalog reindexed.
A practical mapping review should answer these questions for every field:
- Will customers search the value as natural language?
- Will the value be used in an exact filter?
- Will it be sorted or aggregated?
- Does it represent an identifier, a label, or a measurable value?
- Does it require case-insensitive matching or a custom analyzer?
- Can the WooCommerce value contain inconsistent types or empty values?
In practice, product names and descriptions are commonly mapped as text with keyword subfields, while SKUs, slugs, statuses, term IDs, and external IDs are mapped as keyword. Product prices, quantities, ratings, and timestamps should use appropriate numeric or date types.