← Back to Dimensions

Search Results Count Band

Also known as: Search Result Count Band, Number of Search Results Band, Search Results Bucket

ExperiencedimensionE-commerce: Product Discovery & Merchandising (Search/Filters/PDP)E-commerce

Buckets each submitted site search into 0, 1-10, 11-50 or 51+ results. Read from search_results_count on the first results page of view_search_results.

Business Use Case

1️⃣ Search merchandiser: when the 0 band share rises, reviews its top terms and adds synonyms, redirects or products. 2️⃣ Merchandising team: when 51+ searches convert below 1-10, tunes relevance ranking and default facets for those terms. 3️⃣ Product owner: after a search engine or index release, compares band mix week over week to catch recall regressions.

Business Criticality

Medium

Journey / Navigation Area

Discovery

Owning Function

Merchandising

Scope

Event

Calculation Notes

1️⃣ Source: search_results_count on view_search_results (GA4) or Adobe search; page_number = 1 only, refires (is_refire = true) excluded. 2️⃣ Values: 0, 1-10, 11-50, 51+ and (not set). A missing or non-numeric count is (not set), never 0. 3️⃣ Count = total matches the engine returned before pagination, not the number of tiles rendered on the page. 4️⃣ Sort reload: a first-page view repeating the previous search term in the same session is the same search and is not banded again. 5️⃣ Autocomplete suggestions shown while typing are not searches; only submitted searches carry a band. 6️⃣ The 0 band share of all searches equals Zero-Results Search Rate under the same filters. 7️⃣ Internal and bot traffic (traffic_type = internal or bot) is excluded before banding.

Technical Details

Data Typestring
Lookback WindowEvent, Daily, Weekly, Monthly

Events

PlatformEvent
Google Analytics 4view_search_results
Adobesearch

Data Mappings

W3 Data Layer
{
  "digitalData": {
    "event": [
      {
        "eventInfo": {
          "eventName": "view_search_results"
        },
        "attributes": {
          "search_term": "term",
          "search_results_count": 25,
          "page_number": 1,
          "is_refire": false,
          "traffic_type": "external"
        }
      }
    ]
  }
}
GA4 Data Layer
{
  "event": "view_search_results",
  "search_term": "term",
  "search_results_count": 25,
  "page_number": 1,
  "is_refire": false,
  "traffic_type": "external"
}
Adobe Client Data Layer
{
  "event": "search",
  "eventInfo": {
    "eventName": "search"
  },
  "search_term": "term",
  "search_results_count": 25,
  "page_number": 1,
  "is_refire": false,
  "traffic_type": "external"
}
XDM Mapping
{
  "eventType": "search",
  "_<tenantId>": {
    "siteSearch": {
      "searchTerm": "term",
      "searchResultsCount": 25,
      "pageNumber": 1,
      "isRefire": false,
      "trafficType": "external"
    }
  }
}

SQL Queries

Google Analytics 4 (BigQuery)
-- ==========================================
-- 1. GOOGLE BIGQUERY SQL
-- ==========================================
DECLARE start_date DATE DEFAULT DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY);
DECLARE end_date DATE DEFAULT DATE_SUB(CURRENT_DATE(), INTERVAL 1 DAY);

-- First results page of each view_search_results, refires and internal/bot traffic removed, parameters pivoted from event_params
WITH searches AS (
  SELECT
    user_pseudo_id,
    event_timestamp,
    (SELECT value.int_value FROM UNNEST(event_params) WHERE key = 'ga_session_id') AS ga_session_id,
    (SELECT value.string_value FROM UNNEST(event_params) WHERE key = 'search_term') AS search_term,
    (SELECT SAFE_CAST(COALESCE(CAST(value.int_value AS STRING), CAST(value.double_value AS STRING), value.string_value) AS FLOAT64)
       FROM UNNEST(event_params) WHERE key = 'search_results_count') AS results_count
  FROM `your-project.analytics_123456789.events_*`
  WHERE _TABLE_SUFFIX BETWEEN FORMAT_DATE('%Y%m%d', start_date) AND FORMAT_DATE('%Y%m%d', end_date)
    AND event_name = 'view_search_results'
    AND (SELECT COALESCE(value.int_value, SAFE_CAST(value.double_value AS INT64), SAFE_CAST(value.string_value AS INT64)) FROM UNNEST(event_params) WHERE key = 'page_number') = 1
    AND COALESCE((SELECT LOWER(COALESCE(value.string_value, CAST(value.int_value AS STRING))) FROM UNNEST(event_params) WHERE key = 'is_refire'), 'false') NOT IN ('true', '1')
    AND COALESCE((SELECT LOWER(value.string_value) FROM UNNEST(event_params) WHERE key = 'traffic_type'), '') NOT IN ('internal', 'bot')
),
-- Sort reloads: a first-page result view repeating the previous search term in the same session is the same search
first_views AS (
  SELECT
    search_term,
    results_count,
    LAG(search_term) OVER (PARTITION BY user_pseudo_id, ga_session_id ORDER BY event_timestamp) AS previous_term
  FROM searches
)
-- Band each search once; a missing, non-numeric or out-of-range count is (not set), never 0
SELECT
  search_term,
  CASE
    WHEN results_count = 0 THEN '0'
    WHEN results_count BETWEEN 1 AND 10 THEN '1-10'
    WHEN results_count BETWEEN 11 AND 50 THEN '11-50'
    WHEN results_count >= 51 THEN '51+'
    ELSE '(not set)'
  END AS search_results_count_band
FROM first_views
WHERE previous_term IS NULL OR previous_term IS DISTINCT FROM search_term;
Adobe Experience Platform (AEP Query Service)
-- ==========================================
-- 2. ADOBE AEP QUERY SERVICE SQL
-- ==========================================
-- Events in the last 90 days to yesterday with a 30-minute-inactivity session per visitor
WITH events AS (
  SELECT
    identityMap['ECID'][0].id AS ecid,
    timestamp,
    eventType,
    _tenantId.siteSearch.searchTerm AS search_term,
    TRY_CAST(CAST(_tenantId.siteSearch.searchResultsCount AS STRING) AS DOUBLE) AS results_count,
    TRY_CAST(CAST(_tenantId.siteSearch.pageNumber AS STRING) AS INT) AS page_number,
    LOWER(CAST(_tenantId.siteSearch.isRefire AS STRING)) AS is_refire,
    LOWER(_tenantId.siteSearch.trafficType) AS traffic_type,
    SESS_TIMEOUT(timestamp, 60 * 30) OVER (PARTITION BY identityMap['ECID'][0].id ORDER BY timestamp ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS session
  FROM aep_web_events_dataset
  WHERE CAST(timestamp AS DATE) BETWEEN DATE_SUB(CURRENT_DATE, 90) AND DATE_SUB(CURRENT_DATE, 1)
),
-- First results page of each search, refires and internal/bot traffic removed; a first-page search repeating the previous term in the session is a sort reload
first_views AS (
  SELECT
    search_term,
    results_count,
    LAG(search_term) OVER (PARTITION BY ecid, session.num ORDER BY timestamp) AS previous_term
  FROM events
  WHERE eventType = 'search'
    AND page_number = 1
    AND COALESCE(is_refire, 'false') NOT IN ('true', '1')
    AND COALESCE(traffic_type, '') NOT IN ('internal', 'bot')
)
-- Band each search once; a missing, non-numeric or out-of-range count is (not set), never 0
SELECT
  search_term,
  CASE
    WHEN results_count = 0 THEN '0'
    WHEN results_count BETWEEN 1 AND 10 THEN '1-10'
    WHEN results_count BETWEEN 11 AND 50 THEN '11-50'
    WHEN results_count >= 51 THEN '51+'
    ELSE '(not set)'
  END AS search_results_count_band
FROM first_views
WHERE previous_term IS NULL OR previous_term IS DISTINCT FROM search_term;

Source Data

Digital Analytics (GA4 / Adobe Analytics)

Dependencies

Prerequisite: List the dependencies required for this Dimension

Events:

site-search

Report Attributes

Internal Search Term Device Category Page Type Traffic Source

Segment Eligibility

true

Governance

Data SensitivityInternal

Governance

Created bydevyendarm
Created on9/30/2026
Last modified bydevyendarm
Last modified on9/30/2026
Version1.0.0
Validation stateqa passed
StatusPUBLISHED

GitHub

View related Pull Requestcatalog/dimensions/search-results-count-band.yml

Community Discussion