Unified/Hybrid Search Implementation Guide

Overview

Unified/Hybrid Search seamlessly integrates Keyword Search, AI-powered Concept Search, and Image Search into a single, powerful search experience. By combining these search capabilities, Unified/Hybrid Search enhances discoverability, reduces zero-result occurrences, and improves result relevance, ensuring a frictionless and efficient search experience for users.

Key Benefits of Unified/Hybrid Search

  1. Broaden Search Coverage: Uncover more relevant results by merging precise keyword matches with AI-driven concept and image-based results, ensuring no valuable content is overlooked.
  2. Eliminate Zero Results: Provide intelligent fallback results using Concept and Image Search when keyword-based queries return no matches, reducing user frustration and site abandonment.
  3. Boost Relevancy: Rank and prioritize the most meaningful results by intelligently merging keyword, concept, and image search outputs for optimized search accuracy.

Step-by-Step Guide to Configuring Unified/Hybrid Search

Prerequisites

Before configuring Unified/Hybrid Search, ensure the following:

  1. The Unified/Hybrid Search feature must be activated in your account by our internal team.
  2. Concept Search is a required component of Unified/Hybrid Search and must be enabled.
  3. Image Search is optional, if you wish to include Image Search in Unified/Hybrid Search, it must be enabled separately.
  4. To request activation, contact our CSD team via email.
  5. Once activated, you can proceed with configuration.

Configuring Visual and Image Search Fields in Workbench

After enabling Unified/Hybrid Search, follow the steps detailed in Concept Search and Image Search documentation to configure the fields for optimal search performance

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 Unified/Hybrid Search can function as intended. Rebuilding the full index integrates all the setup changes and prepares the system for executing visual and image searches. Please note that this process involves creating a new index and updating all related components, as detailed in the provided documentation.

Validate the Results

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

📘

Tips

Guidelines for Testing Unified/Hybrid Search

  1. Run diverse test queries to validate keyword, concept, and image-based retrieval.
  2. Compare traditional keyword search with Unified/Hybrid Search to evaluate improvement in coverage and relevancy.
  3. Ensure fallback functionality is working by testing queries that would otherwise return zero results.
  4. Unified/Hybrid Search intelligently combines results from multiple search methods to provide a well-rounded search experience. If some expected results don’t appear, it doesn’t necessarily mean something is wrong—fine-tuning can help optimize search performance. If you’d like to refine your search results further, don’t hesitate to reach out to our CSD team for personalized adjustments!

Fine-Tuning the Results

To optimize Unified/Hybrid Search performance, you can adjust the boost values (weighting) for each search type.

Adjusting Boost Values

  1. Navigate to Admin in the Workbench
  2. Go to the System Parameter section
  3. Select Hawk AI Configuration as the group
  4. You will then see system parameters for adjusting the boost values of each search type.
    1. Default Boost Values: The default system parameter for the boost value of each search type is set to 0, meaning they are equally weighted. This does not indicate that any search type is inactive or has no impact. Instead, it ensures that all search types contribute equally to Unified/Hybrid Search results until adjustments are made.
    2. If Image Search is not enabled in your account or included in your Unified/Hybrid Search solution, you may not see a system parameter for Image Search.
    3. If you believe you should, please reach out to our support team for assistance.

Guide to Fine-Tuning Boost Values

  1. Start with the most relevant search type for your use case:
    1. If your users frequently search with varied keywords or broad intent, adjust the Concept Search boost value first.
      1. Example queries best suited for Concept Search
        1. "comfortable ergonomic office chair"
        2. "furniture for small apartment living"
        3. "best running shoes for flat feet"
    2. If your users primarily search using visual descriptions or look-and-feel terms, adjust the Image Search boost value first.
      1. Example queries best suited for Image Search
        1. "striped summer dress with floral patterns"
        2. "glossy teal high heels"
        3. "modern black sneakers"
  2. Once your primary search type's search results are refined to meet your desired outcomes, check the other search types to ensure they still handle different query types effectively. This step is important because adjusting one search type may impact how other search types contribute to the final results.
    1. Example: If Keyword Search dominate the results but your users are searching with descriptive queries, increasing the Concept Search boost can help. Likewise, if visually distinct items are not surfacing well, adjusting the Image Search boost can improve their ranking.
    2. Continue iterating on adjustments while testing a diverse range of user queries to maintain a well-balanced Unified/Hybrid Search experience.

Examples

Prioritizing Concept Search
  1. Scenario: A furniture store wants users to find items based on descriptions like "functional dining setup for a small family" rather than strict keyword matches.
  2. Adjustment: Increase the Concept Search boost value so that queries with broader intent return the most relevant results.
  3. Verification: Test search queries like "functional dining setup for a small family" or "dining table for family gatherings" to confirm that they return products that match the conceptual intent, even if the exact keywords aren't present in the product title.
Prioritizing Image Search
  1. Scenario: A fashion retailer wants users to search by style descriptions like "red floral summer midi dress".
  2. Adjustment: Increase the Image Search boost value so that visually similar items rank higher.
  3. Verification: Search for "red floral summer midi dress" or "vintage-inspired floral gown" and confirm that the results include products that match the described style and aesthetic, rather than just keyword-based matches.

Making Search Request

Once Unified/Hybrid Search is configured and validated, users can start making search requests using the Unified/Hybrid Search request type via the Search API. This facilitates seamless integration with your search system, enhancing the overall search experience. For more details please refer to our Search API documentation.

Example Request - Unified/Hybrid Search:

{
    "ClientGuid": "xxxxx",
    "RequestType":"UnifiedSearch",
    "Keyword": "cooking gears for hiking trips in summer"
}

Troubleshooting Common Issues

IssuePossible CauseSolution
Keyword search is working, but concept/image search results are not includedThe appropriate fields for Concept or Image Search may not be configured correctlyReview field selection in the Concept or Image Search settings
Unified/Hybrid Search is not returning expected resultsConcept Search may not be enabledVerify that Concept Search is activated in the Workbench
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
Some expected results are missing or Concept or Image Search doesn't seem to be working after being enabledIndex rebuild may not have been completed successfully, or Visual/Image Search might not be correctly configuredPerform another full index rebuild, verify field selection, and ensure that Search is properly configured

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

Frequently Asked Questions

  1. If a Keyword search doesn’t return any results, will Unified/Hybrid Search help?
    Yes, Unified/Hybrid Search ensures you still receive relevant results. If a Keyword Search does not return any items, Unified/Hybrid Search automatically uses Concept Search to find contextually relevant results. This reduces the chances of empty search results and improves the user experience.
  2. Will products appear twice if they are found in both Keyword and Concept Search?
    No, Unified/Hybrid Search intelligently eliminates duplicates. When a product appears in both Keyword and Concept Search results, it is displayed only once. Additionally, these common products are automatically boosted higher in the results for improved relevancy.
  3. Why does Unified/Hybrid Search sometimes return fewer results than a Keyword search? Isn’t it supposed to show more?
    Unified/Hybrid Search generally returns more results by combining Keyword Search with AI-powered Concept Search. However, keyword-only searches may include additional results by matching partial keywords, which can increase the total number of items but may reduce overall relevancy.
  4. If Keyword search returns 20 items and Concept Search returns 30 items, will Unified/Hybrid Search return 50 items?
    If there is no overlap between the two sets of results, Unified/Hybrid Search will return 50 items (20 from Keyword Search + 30 from Concept Search). However, if some products appear in both searches, Unified/Hybrid Search will removes duplicates and displays these common products only once. The total number of Unified/Hybrid Search results will always be less than or equal to the sum of Keyword Search and Concept Search results.
  5. Can I control the priority of results between Keyword search and Concept Search in Unified/Hybrid Search?
    Yes, we offer flexibility to prioritize results from either Keyword Search or Concept Search based on your business goals by adjusting the boost value of each search type. If you’d like more control over how these results are balanced or displayed, our internal team can help configure this for you. We also offer the option to switch to different embedding models depending on the use case, or we can work with you if you have your own embedding model. For more details on these advanced capabilities, please connect with our CSD team to discuss your preferences and ensure the search results align with your specific needs.

Front-End Implementation

To use Unified/Hybrid 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 Unified/Hybrid Search by simply including the following component:

Unified/Hybrid Search Component:

<div class="unifiedsearch-field">
    <input type="text" hawksearch-input hawksearch-unified-search value="{{query}}" placeholder="{{strings.placeholder}}" />
    <hawksearch-autocomplete></hawksearch-autocomplete>
</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.3.0 or newer. If you are on an older version, please update to 6.3.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 Unified/Hybrid Search component in the appropriate section of your UI.

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

Code Example

<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'
                }
              },
              'unifiedsearch-field': {
                strings: {
                  placeholder: 'Describe what you are looking for...'
                }
              },
              'conceptsearch-field': {
                strings: {
                  placeholder: 'Search by a Concept'
                }
              },
              '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>
      
      <!-- UNIFIED 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-unifiedsearch-field style="flex: 1;"></hawksearch-unifiedsearch-field>
          </div>
        </div>
      </div>

      <div style="margin-top: 16px;">
        <hawksearch-search-results></hawksearch-search-results>
      </div>
    </div>
  </body>
</html>