Concept Search Implementation Guide

Overview

Concept Search introduces an advanced approach to optimizing search results by understanding the contextual and semantic meaning of user inputs. Unlike traditional keyword-based searches, Concept Search interprets queries based on intent, ensuring that search results are more aligned with what users are genuinely looking for. This significantly enhances search accuracy and user satisfaction.

Step-by-Step Guide to Configuring Concept Search

Prerequisites

Before configuring Concept Search, ensure the following:

  1. The Concept Search feature must be activated in your account by our internal team.

  2. To request activation, contact our CSD team via email or submit an interest form within the Workbench.

  3. Once activated, you can proceed with configuration.

Configuring Concept Search Fields in Workbench

After enabling Concept Search, follow these steps to configure the fields for optimal search performance:

Step 1 - Access Concept Search Admin

  1. Please go to the Workbench
  2. Please click on the Concept Search in the left navigation

Step 2 - Search for Fields

  1. The first search field allows you to search for the name of an existing Field. If you know the name as it appears in the data feed, or a keyword from the name, type it into the "Field Name"
  2. Search a field based on the type of Field by selecting an option in the drop down.
    1. Field values indexed "as is" AND are stemmed
    2. Field values are NOT stemmed
      Field values are ONLY stemmed (search only)
    3. Stored only, not used for search nor facets
  3. Search a field based on the Data Type by selecting an option in the drop down.
    1. Boolean
    2. Datetime
    3. GeoPoint
    4. Numeric
    5. Text
  4. You can also conduct a search based on the label of the Field. This name may differ from the corresponding field in the data field.
  5. To search for a Field by any tags associated with it, enter the tags here.
  6. Once you have added all search criteria, click the "Search" button to see your results.
  7. You can also clear the search criteria to see all the fields.

Step 3 - Choose the Right Fields for Concept Search

Concept Search relies on textual content to generate embeddings. Selecting the appropriate field(s) ensures that Concept Search functions effectively. Keep in mind that the system imposes a total 512-token limit for embeddings.

📘

Tips

  1. A 512-token limit roughly translates to approximately 800 words or around 2,000 characters, depending on the text's complexity and formatting.
  2. Choose fields that provide meaningful content that best represents your data. For instance, if your index consists of product data, selecting the Short Description or Title field may yield the best results.

Suggested Fields to Get Started

  1. Short Description: Provides concise, high-value summaries of products or content.
  2. Long Description: Contains detailed information useful for capturing the full context of an item.
  3. Title: Gives an initial context for products or content, useful for a broad match.
  4. Category: Helps categorize and group similar content, improving relevance in search.

Unsure which fields contain the most meaningful content?

No worries! You can check by following these steps:


  1. Navigate to Preview
  2. Select Default Search as Preview Type
  3. From any item in the search results, click on the Score tag
  4. In the popup, click on Explain
  5. Another popup for Item Information will appear, click on Info & Field Matches
  6. Review the fields and values listed to see which contain the most meaning ful content for Concept Search
    1. For example, in the 2nd screenshot, the Title and Description fields often contain rich contextual information about an item, making them ideal for Concept Search embeddings.
    2. However, fields like SKU may not be as useful since they typically contain identifiers rather than descriptive content.

Step 4 - Rebuild the Index

After configuring the fields, a crucial step is to rebuild the full index. This process allows the system to create the necessary embeddings for the configured field, ensuring that the Concept Search can function as intended. Rebuilding the full index integrates all the setup changes and prepares the system for executing concept searches. Please note that this process involves creating a new index and updating all related components, as detailed in the provided documentation.

Step 5 - Validate the Results

Once the index rebuild is complete, let's validate that Concept Search is working as expected.

  1. Navigate to Preview in the Workbench.
  2. Select Smart Search as the Preview Type
  3. Turn on Concept Search
  4. Enter test queries related to your dataset.
  5. Review the search results to confirm that Concept Search is returning relevant content.

📘

Tips

Guidelines for Testing Concept Search

  1. Test with Variations: Use different phrasings of similar queries to check if Concept Search correctly identifies intent.
  2. Use Descriptive Queries: Concept Search is designed to understand meaning, so test with full phrases rather than just keywords.
  3. Compare with Standard Search: Run the same query using traditional search to compare how Concept Search improves the results.
  4. Concept Search focuses on understanding broad concepts rather than exact matches. If specific results do not appear, it does not necessarily indicate a problem. Advanced fine-tuning is available separately for custom adjustments. If you need more fine-tuning for custom adjustments, feel free to reach out to our CSD team—we’re happy to help you get the best results for your specific needs!

Step 6 - Making Search Request

Once Concept Search is configured and validated, you can start making search requests using the Concept Search request type through the Search API. This enables seamless integration with your search solution, leveraging Concept Search for improved query understanding and result relevance. For more details please refer to our Search API documentation.

Example Request:

{
    "ClientGuid": "xxxxx",
    "RequestType":"ConceptSearch",
    "kValue":3,
    "Keyword": "Show me products that are good for cooking on a hiking trip"
}

Troubleshooting Common Issues

IssuePossible CauseSolution
Concept Search is not returning relevant resultsSelected fields may not contain useful textual descriptionsReview and adjust field selection to include meaningful content
Concept Search returns too many unrelated resultsFields may contain overly generic contentNarrow the field selection to more descriptive fields
Feature is not available in WorkbenchConcept Search has not been enabledContact the CSD Team to activate the feature
Some expected results are missing or Concept Search doesn't seem to be working after being enabledIndex rebuild may not have been completed successfully, or Concept Search might not be correctly configuredPerform another full index rebuild, verify field selection, and ensure that Concept Search is properly configured
API request is failing or returning errorsThe request may not be properly formattedEnsure that the JSON structure is correct and that required fields such as ClientGuid and correct RequestType are included

If issues persist after following these solutions, please reach out to our support team for further assistance.

Front-End Implementation

To use Concept Search on your frontend, you can either integrate it using our Search API or take advantage of our prebuilt Rapid UI framework to streamline implementation.

Rapid UI

If you are using Rapid UI to build your frontend, you can add Concept Search by simply including the following component:

Concept Search Component:

<div class="search-field">
    <input type="text" hawksearch-input hawksearch-concept-search value="{{query}}" placeholder="{{strings.placeholder}}" />
</div>

Steps to Implement in Rapid UI

  1. Ensure you are using Rapid UI in your frontend setup.

  2. Check your Rapid UI version: This feature is only available in Rapid UI 6.1.0 or newer. If you are on an older version, please update to 6.1.0.

  3. Verify your HawkSearch configuration by confirming that your clientId is correctly set and updated (to avoid uisng ourdated or incorrect values)

    1. ClientId can be located at: Admin > Account Info > Setup Info > Client Guid / Tracking Key

  4. Verify your API endpoint configuration

    1. Ensure that your endpoint is pointing to the correct environment (e.g., production instead of development)

  5. Add the Concept Search component in the appropriate section of your UI.

    <div class="search-field">
        <input type="text" hawksearch-input hawksearch-concept-search value="{{query}}" placeholder="{{strings.placeholder}}" />
    </div>
    

Code Example

  1. <html lang="en">
      <head>
        <title>Rapid UI Smart Search Example</title>
        <meta name="viewport" content="width=device-width,initial-scale=1">
        <!-- CUSTOM STYLES - ADDED FOR DEMO PURPOSE -->
        <style type="text/css">
          body{font-family:Arial,Helvetica,sans-serif;font-size:16px;}
          .smartsearchdemo__container {margin: 0 auto;min-width: 340px;max-width: 1280px;}
          .smartsearchdemo__container .search-field__container,.smartsearchdemo__container .conceptsearch-field__container {display: flex;justify-content: space-around;gap: 12px;}
          .smartsearchdemo__container .search-field__bar{display: flex;justify-content: space-around;background-color: #f5f7fa;padding: 0px 16px;align-items: center;flex: 1 0 0;border-radius: 100px;border: 1px solid #e6e9ed;transition: all .25s ease-in-out;}
          .smartsearchdemo__container .search-field__bar:focus,.smartsearchdemo__container .search-field__bar:hover,.smartsearchdemo__container .search-field__bar:focus-within,.smartsearchdemo__container .search-field__bar:target,.smartsearchdemo__container .search-field__bar:focus-visible,
          .smartsearchdemo__container .search-field__actions .search-field__actions__button:focus,.smartsearchdemo__container .search-field__actions .search-field__actions__button:hover,.smartsearchdemo__container .search-field__actions .search-field__actions-button:focus-within,
          .smartsearchdemo__container .search-field__actions .search-field__actions__button:target,.smartsearchdemo__container .search-field__actions .search-field__actions__button:focus-visible {border: 1px solid #119FF7;background: #FFF;}
          .smartsearchdemo__container .search-field__bar .search-field__bar__icon {display: flex;align-items: center;justify-content: center;width: 40px;height: 40px;margin: 0;max-width: 7.5rem;vertical-align: top;}
          .smartsearchdemo__container .search-field__bar .search-field__bar__link {color: #656D78;padding: 16px 24px;cursor: pointer;}
          .smartsearchdemo__container .search-field__bar .search-field__bar__divider{display: flex;border-left: 1px solid #e6e9ed;height: 100%;}
          .smartsearchdemo__container .search-field__actions .search-field__actions__button {display: flex;padding: 16px;align-items: center;align-self: stretch;border-radius: 100px;border: 1px solid #e6e9ed;background: #f5f7fa;transition: all .25s ease-in-out;cursor: pointer;}
          .smartsearchdemo__container .search-field__actions .search-field__actions__icon {width: 20px;height: 20px;}
          .smartsearchdemo__container .visualsearch-field__dialog {display: flex;position: relative;box-sizing: border-box;max-width: 1280px;padding: 32px;flex-direction: column;justify-content: center;align-items: flex-start;gap: 32px;border-radius: 25px;border: 1px solid #119ff7;background: #fff;}
          .smartsearchdemo__container .visualsearch-field__dialog .visualsearch-field__dialog__title {display: flex;justify-content: space-between;width: 100%;}
          .smartsearchdemo__container .visualsearch-field__dialog .visualsearch-field__dialog__title > h2 {display: block;margin: 0;color: #353b48 !important;font-size: 18px;font-style: normal;font-weight: 700;line-height: 100%;letter-spacing: .2px;}
          .smartsearchdemo__container .visualsearch-field__dialog .visualsearch-field__dialog__body {display: flex;width: 100%;flex-direction: column;}
          .smartsearchdemo__container .visualsearch-field__close {display: flex;align-items: center;justify-content: center;width: 56px;height: 56px;margin: 0;position: absolute;top: 1px;right: 1px;box-sizing: border-box;vertical-align: top;border: none;background: #fff;border-radius: 50%;cursor: pointer;}
          .smartsearchdemo__container .visualsearch-field__close:hover {background-color: #F5F7FA }
        </style>
        <!-- CUSTOM JAVASCRIPT TO HANDLE TABS - ADDED FOR DEMO PURPOSE -->
        <script>function getRequestTypeIndex(e){const t=e.get("requestType");return t?"ConceptSearch"===t?1:"ImageSearch"===t?2:0:0}document.addEventListener("DOMContentLoaded",(function(){let e=getRequestTypeIndex(new URL(document.location).searchParams)||0;function t(t){if(t.preventDefault(),"keypress"===t.type&&13===t.which||"click"===t.type){let t=parseInt(this.dataset.tabIndex);t!==e&&document.querySelectorAll(".smartsearchdemo__container .tab-container").forEach((function(n){if(parseInt(n.dataset.tabIndex)===t)return document.querySelectorAll(".tab-container").forEach((function(e){e.style.display="none"})),n.style.display="block",void(e=parseInt(n.dataset.tabIndex))}))}}document.querySelectorAll(".tab-container").forEach((function(t){parseInt(t.dataset.tabIndex)===e?t.style.display="block":t.style.display="none"})),document.querySelectorAll(".tab-switcher").forEach((function(e){e.addEventListener("click",t),e.addEventListener("keypress",t)}))}));</script>
        <!-- Rapid UI LIBRARY -->
        <script type="module" src="https://cdn.jsdelivr.net/npm/@bridgeline-digital/[email protected]/dist/hawksearch-handlebars-ui.min.js"></script>
        <!-- HAWKSEARCH CONFIGURATION -->
        <script type="text/javascript">
          addEventListener('hawksearch:loaded', () => {
            HawkSearch.init({
                clientId: "59d7b9ce967d4fdf8262d1a49392b8be",
                components: {
                  'search-field': {
                    strings: {
                      placeholder: 'Search by Keyword'
                    }
                  },
                  'conceptsearch-field': {
                    strings: {
                      placeholder: 'Search by a Concept'
                    }
                  },
                  'imagesearch-field': {
                    strings: {
                      placeholder: 'Describe an image'
                    }
                  },
                  'visualsearch-field': {
                    template: 'visualsearch-field__template',
                    strings: {
                      dragImageMessage: 'Search By Image',
                      dropImageMessage: 'Drop an image here'
                    }
                  },
                  'search-results-item': {
                      template: 'search-results-item__template'
                  }
                },
                search: {
                  url: window.location.pathname,
                  endpointUrl: "https://searchapi-dev.hawksearch.net"
                },
                urlPrefixes: {
                  assets: "https://dev.hawksearch.net",
                  content: "https://preview-dev.hawksearch.net/developerportalsandbox",
                },
                css: {
                  customStyles: 'custom-styles__template'
                },
                debug: true
            });
          });
        </script>
      </head>
      <body>
        <div class="smartsearchdemo__container">
          <!-- CSS TEMPLATE USED TO CUSTOMIZE HANDLEBAR-UI NATIVE STYLES -->
          <template id="custom-styles__template">
            <style type="text/css">
              input[type="text"]:not(.facet__search) {border: none;background-color: transparent;}
              input[type="text"]:not(.facet__search):focus,
              input[type="text"]:not(.facet__search):hover,
              input[type="text"]:not(.facet__search):focus-within,
              input[type="text"]:not(.facet__search):target,
              input[type="text"]:not(.facet__search):focus-visible {outline: none;border: none;background-color: transparent;}
              .visualsearch-field__drop-area {display:flex;padding:40px 24px;flex-direction:column;align-items:center;gap: 24px;align-self:stretch;border-radius:8px;border:1px solid #e6e9ed;}
              .visualsearch-field__drop-area.dragging-state {border: 1px dashed #119ff7;background: #f2faff;}
              .visualsearch-field__drop-area.dragging-state > .visualsearch-field__drop-area__prompt-msg,
              .visualsearch-field__drop-area.dragging-state > .visualsearch-field__drop-area__upload-button,
              .visualsearch-field__drop-area.dragging-state > .visualsearch-field__drop-area__icon {pointer-events: none;visibility: hidden;}
              .visualsearch-field__drop-area__upload-button {display:flex;padding:12px 40px 12px 32px;align-items:center;gap:10px;color:#fff !important;background-color:#000;cursor:pointer;}
              .visualsearch-field__drop-area__prompt-msg {color:#000;text-align:center;font-size:18px;font-style:normal;font-weight:700;line-height:100%;letter-spacing:.2px;}
              .visualsearch-field__drop-area__drop-msg {pointer-events: none;color: #119ff7 !important;text-align:center;font-size:18px;font-style:normal;font-weight:700;line-height:100%;letter-spacing:.2px;}
            </style>
          </template>
        
          <!-- CUSTOM TEMPLATE TO MODIFY THE VISUALS OF <visualsearch-field /> COMPONENT -->
          <template id="visualsearch-field__template">
            <div class="visualsearch-field">
              <div class="visualsearch-field__drop-area" hawksearch-visualsearch-droparea>
                <hawksearch-icon name="drop-image" size="100"></hawksearch-icon>
                <p class="visualsearch-field__drop-area__prompt-msg">{{strings.dragImageMessage}}</p>
                <p class="visualsearch-field__drop-area__drop-msg">{{strings.dropImageMessage}}</p>
                <label class="visualsearch-field__drop-area__upload-button">
                  <input hawksearch-visualsearch-fileinput type="file" accept="image/*" capture="environment">
                  <hawksearch-icon name="upload" size="20"></hawksearch-icon>
                  {{strings.uploadImageMessage}}
                </label>
                <div class="visualsearch-field__drop-area__image-display" hawksearch-visualsearch-display></div>
              </div>
            </div>
          </template>
          
          <!-- CUSTOM TEMPLATE TO MODIFY THE VISUALS OF <search-results-item__template-field /> COMPONENT -->
          <template id="search-results-item__template">
            <div class="search-results-list__item search-results-list__item--{{type}}">
                {{#if pinned}}
                <span class="search-results-list__item__pin">
                    <hawksearch-icon name="star"></hawksearch-icon>
                </span>
                {{/if}}
                {{#if (lt salePrice price)}}
                <span class="search-results-list__item__sale-indicator">{{strings.sale}}</span>
                {{/if}}
                <a hawksearch-link href="{{url}}" class="search-results-list__item__image" aria-label="{{title}}">
                    <img hawksearch-image src="{{imageUrl}}" alt="">
                </a>
                <div class="search-results-list__item__title">
                    <a hawksearch-link href="{{url}}">{{title}}</a>
                </div>
                {{#if rating}}
                <hawksearch-rating rating="{{rating}}"></hawksearch-rating>
                {{/if}}
                {{#unless (eq price undefined)}}
                <div class="search-results-list__item__price" itemprop="offers" itemtype="http://schema.org/Offer" itemscope>
                    {{#if (lt salePrice price)}}
                    <span class="search-results-list__item__price__original">{{currency price}}</span>
                    <span class="search-results-list__item__price__current" itemprop="price">{{currency salePrice}}</span>
                    {{else}}
                    <span class="search-results-list__item__price-__current" itemprop="price">{{currency price}}</span>
                    {{/if}}
                </div>
                {{/unless}}
                <hawksearch-variant-selector></hawksearch-variant-selector>
            </div>
          </template>
          
          <!-- KEYWORD SEARCH TAB -->
          <div class="tab-container" data-tab-index="0">
            <div class="search-field__container">
              <div class="search-field__bar">
                <span class="search-field__bar__icon">
                  <hawksearch-icon name="search" size="20"></hawksearch-icon>
                </span>
                <hawksearch-search-field style="flex: 1;"></hawksearch-search-field>
                <div class="search-field__bar__divider"></div>
                <a class="search-field__bar__link tab-switcher" data-tab-index="1">or Concepts</a>
              </div>
              <div class="search-field__actions">
                <a class="search-field__actions__button tab-switcher" data-tab-index="2">
                  <hawksearch-icon name="image" size="20"></hawksearch-icon>
                </a>
              </div>
            </div>
          </div>
    
          <!-- CONCEPT SEARCH TAB -->
          <div class="tab-container" data-tab-index="1">
            <div class="search-field__container">
              <div class="search-field__bar">
                <span class="search-field__bar__icon">
                  <hawksearch-icon name="search" size="20"></hawksearch-icon>
                </span>
                <hawksearch-conceptsearch-field style="flex: 1;"></hawksearch-conceptsearch-field>
                <div class="search-field__bar__divider"></div>
                <a class="search-field__bar__link tab-switcher" data-tab-index="0">or Keywords</a>
              </div>
              <div class="search-field__actions">
                <a class="search-field__actions__button tab-switcher" data-tab-index="2">
                  <hawksearch-icon name="image" size="20"></hawksearch-icon>
                </a>
              </div>
            </div>
          </div>
    
          <!-- VISUAL SEARCH TAB -->
          <div class="tab-container" data-tab-index="2">
            <div class="visualsearch-field__dialog">
              <a class="visualsearch-field__close tab-switcher" data-tab-index="1" tabindex="0">
                <hawksearch-icon name="cross" size="20"></hawksearch-icon>
              </a>
              <div class="visualsearch-field__dialog__title">
                <h2>Visual Search</h2>
              </div>
              <div class="visualsearch-field__dialog__body">
                <hawksearch-visualsearch-field></hawksearch-visualsearch-field>
                <div class="search-field__bar">
                  <span class="search-field__bar__icon">
                    <hawksearch-icon name="search" size="20"></hawksearch-icon>
                  </span>
                  <hawksearch-imagesearch-field style="flex: 1;"></hawksearch-imagesearch-field>
                </div>
              </div>
            </div>
          </div>
          <div style="margin-top: 16px;">
            <hawksearch-search-results></hawksearch-search-results>
          </div>
        </div>
      </body>
    </html>