Cómo crear sugerencias de búsqueda específicas y correcciones de búsquedas de búsqueda

blog-search-results-dark-720x420.png

Tienes una oportunidad para mantener a los compradores en tu sitio web de comercio electrónico con resultados de búsqueda relevantes. Según Harris Poll, el 76 % de los compradores en línea abandonan un sitio web minorista después de una búsqueda fallida.

Por lo tanto, es fundamental optimizar tu experiencia de búsqueda para que los compradores puedan encontrar lo que necesitan rápidamente. Esa es la teoría detrás de una experiencia de búsqueda moderna: hoy en día no es suficiente simplemente proporcionar una barra de búsqueda que devuelva productos coincidentes. Tu sitio de comercio electrónico debe incluir un conjunto completo de herramientas de búsqueda que guíen personalmente a los usuarios a los productos que desean.

En este blog, aprenderás cómo comenzar a mejorar la búsqueda de comercio electrónico agregando dos funciones comunes: sugerencias específicas y correcciones de búsqueda, también conocidas como "¿Quiso decir?"

Ten en cuenta que los siguientes ejemplos se han probado con Elastic 8.5. 

Sugerencias específicas 

Un desafío común entre los minoristas de comercio electrónico son los grandes catálogos de productos con muchas categorías diferentes. En esta situación, es difícil parsear una búsqueda simple para comprender en qué dominio o categoría podría estar interesado un usuario. Por ejemplo, si un usuario busca "pantalla plana" en una tienda minorista de productos electrónicos, es posible que vea resultados en televisores, soportes de televisores, monitores de computadora, etc. Presentar soportes de TV de pantalla plana mientras el usuario busca un televisor puede no ser relevante en esta etapa de su proceso de compra.

Las sugerencias específicas ayudan a sus usuarios a reducir sus búsquedas en los temas que más les interesan al sugerir consultas dentro de categorías o marcas específicas.

Esta es una característica poderosa para ayudar a los usuarios a ver un conjunto de resultados refinado rápidamente. Implementar sugerencias de búsqueda específicas mediante Search UI y Elastic también es simple. En la siguiente sección se te guía a través de cómo crearlo. 

Recopilar datos para sugerencias

Como se describe en el ejemplo anterior, a medida que los usuarios escriben, se les presentarán búsquedas sugeridas y elementos específicos asociados. Para crear esas sugerencias, es una práctica común usar datos de analíticas para recopilar las búsquedas y elementos específicos más comunes con los que los clientes suelen asociarlos.

Por ejemplo, supongamos que al revisar los datos de analíticas de nuestro sitio web de comercio electrónico, descubrimos que la búsqueda principal es "televisor LCD" y que los productos en los que los usuarios hacen clic con más frecuencia se encuentran en la categoría "TV y cine en casa".

Con estos datos, podemos crear un documento que represente una sugerencia específica correspondiente, como este: 

{
   "name": "lcd tv",
   "weight": 112,
   "category": {
       "name": "TV & Home Theater",
       "value": 111
   }
}

Este documento contiene una búsqueda y una categoría asociada. Esto se puede hacer más complejo  si es necesario; por ejemplo, podemos tener una lista de categorías o agregar otro elemento específico, como "marcas".

Luego creamos un índice dedicado en Elasticsearch, en nuestro caso lo llamamos "sugerir", para almacenar una lista de sugerencias de alcance que creamos utilizando los datos de analíticas. Esto se puede hacer mediante transformaciones de datos o código personalizado, como una secuencia de comandos de Python. El ejemplo de mapeo de índice para nuestro índice "sugerir"  se puede encontrar aquí

Sugerencias de autocompletar

Ahora que tenemos nuestra lista de sugerencias lista para ser consumida, debemos agregarla a nuestra experiencia de búsqueda.

Usando Search UI, toma solo unos minutos crear una experiencia de búsqueda sobre Elastic. Luego podemos usar nuestra interfaz recién construida como base para nuestras sugerencias específicas.

Search UI utiliza un objeto de configuración para adaptar la búsqueda a tus necesidades. A continuación, se muestra un fragmento del objeto de configuración que corresponde a la configuración de la sugerencia. En este caso, especificamos el índice y los campos a consultar y los campos a devolver como parte de los resultados:

suggestions: {
     types: {
       popularQueries: {
         search_fields: {
           "name.suggest": {} // fields used to query
         },
         result_fields: {
           name: {
             raw: {}
           },
           "category.name": {
             raw: {}
           }
         },
         index: "suggest",
         queryType: "results"
       }
     },
     size: 5
   }

Luego configuramos el componente SearchBox para pasar la categoría como parte de la búsqueda al navegar a la página de resultados de búsqueda:

// Search bar component
<SearchBox
   onSelectAutocomplete={(suggestion, config, defaultHandler) => {
       // User selects a scoped suggestion - Category
       if (suggestion.name && suggestion.category) {
           const params = { q: suggestion.name.raw, category: suggestion.category.raw.name };
           // Navigate to search result page with category passed as parameters
           navigate({
               pathname: '/search',
               search: `?${createSearchParams(params)}`,
           });
       // User selects normal suggestion
       } else if (suggestion) {
           // Navigate to search result page
           window.location.href = "/search?q=" + suggestion.suggestion;
       }
       defaultHandler(suggestion);
   }}
   autocompleteSuggestions={{
       popularQueries: {
           sectionTitle: "Popular queries",
           queryType: "results",
           displayField: "name",
           categoryField: "category"
       }
   }}
   autocompleteView={AutocompleteView}
/>

Ten en cuenta que pasamos una función AutocompleteView para personalizar la vista de autocompletar para que podamos mostrar la categoría junto con la búsqueda sugerida. 

A continuación, se muestra un fragmento de código de la función AutocompleteView que muestra cómo mostrar una búsqueda con el elemento específico asociado: 

{suggestions.slice(0,1).map((suggestion) => {
   index++;
   const suggestionValue = getDisplayField(suggestion)
   const suggestionScope = getCategoryField(suggestion)
   return (
     <li
       {...getItemProps({
         key: suggestionValue,
         index: index - 1,
         item: {
           suggestion: suggestionValue,
           ...suggestion.result
         }
       })}
     >
       <span>{suggestionValue}</span>
       <ul><span style={{marginLeft: "20px"}}>in {suggestionScope}</span></ul>
     </li>
   );
})}

Luego, en la página de resultados de búsqueda, simplemente necesitamos procesar los parámetros de búsqueda y filtrar el conjunto de resultados: 

 const [searchParams] = useSearchParams();
   useEffect(() => {
       if (searchParams.get('category')) addFilter("department", [searchParams.get('category')], "all")
   }, [searchParams]);

Una vez que ponemos todo junto, el resultado se ve así:

Video thumbnail

Correcciones de búsqueda, también conocidas como "¿Quiso decir?"

Los compradores pueden sentirse frustrados cuando no ven resultados de búsqueda relevantes debido a una mala elección de los términos de búsqueda o un error tipográfico. Para evitar que no se devuelvan resultados de búsqueda o que se devuelvan muy pocos, se recomienda sugerir una búsqueda mejor, comúnmente conocida como "¿Quiso decir?"

Hay muchas formas diferentes de implementar esta característica, pero esta es la forma más sencilla de crearla utilizando Search UI y Elastic. 

Analizar los datos

El conjunto de datos que usaremos para crear la característica "¿Quiso decir?" es similar al que usamos para las sugerencias específicas, por lo que puede sugerir una búsqueda popular a los usuarios en caso de que la búsqueda no arroje resultados.  

Usa una estructura de documento similar para "¿Quiso decir?"

{
   "name": "lcd tv",
   "weight": 112,
   "category": {
       "name": "TV & Home Theater",
       "value": 111
   }
}

La clave de este paso es la forma en que se indexan los datos en Elasticsearch. Para proporcionar sugerencias relevantes, deberás usar características específicas que ofrece Elasticsearch, como los analizadores personalizados.

A continuación, se muestran las configuraciones y mapping de índice utilizadas en nuestro ejemplo: 

{
    "settings":
    {
        "index":
        {
            "number_of_shards": 1,
            "analysis":
            {
                "analyzer":
                {
                    "trigram":
                    {
                        "type": "custom",
                        "tokenizer": "standard",
                        "filter":
                        [
                            "lowercase",
                            "shingle"
                        ]
                    },
                    "reverse":
                    {
                        "type": "custom",
                        "tokenizer": "standard",
                        "filter":
                        [
                            "lowercase",
                            "reverse"
                        ]
                    }
                },
                "filter":
                {
                    "shingle":
                    {
                        "type": "shingle",
                        "min_shingle_size": 2,
                        "max_shingle_size": 3
                    }
                }
            }
        }
    },
    "mappings":
    {
        "properties":
        {
            "category":
            {
                "properties":
                {
                    "name":
                    {
                        "type": "text",
                        "fields":
                        {
                            "keyword":
                            {
                                "type": "keyword",
                                "ignore_above": 256
                            }
                        }
                    },
                    "value":
                    {
                        "type": "long"
                    }
                }
            },
            "name":
            {
                "type": "search_as_you_type",
                "doc_values": "false",
                "max_shingle_size": 3,
                "fields":
                {
                    "reverse":
                    {
                        "type": "text",
                        "analyzer": "reverse"
                    },
                    "suggest":
                    {
                        "type": "text",
                        "analyzer": "trigram"
                    }
                }
            },
            "weight":
            {
                "type": "rank_feature",
                "fields":
                {
                    "numeric":
                    {
                        "type": "integer"
                    }
                }
            }
        }
    }
}

Consulta la documentación de sugerencias para obtener más detalles sobre por qué usar configuraciones y mapping específicas para recuperar sugerencias relevantes. 

Preparar la búsqueda

Ahora que tu índice está listo, puedes trabajar en la experiencia de búsqueda. Para recuperar sugerencias basadas en una búsqueda, aprovecha la API de Elasticsearch. Si no deseas agregar demasiada complejidad en el lado del cliente, crea una plantilla de búsqueda en Elasticsearch que contendrá la consulta. Luego, desde el lado del cliente, solo tienes que ejecutar esa plantilla de búsqueda:

PUT _scripts/did-you-mean-template
{
   "script": {
       "lang": "mustache",
       "source": {
           "suggest": {
               "text": "{{query_string}}",
               "simple_phrase": {
                   "phrase": {
                       "field": "name.suggest",
                       "size": 1,
                       "direct_generator": [
                           {
                               "field": "name.suggest",
                               "suggest_mode": "always"
                           },
                           {
                               "field": "name.reverse",
                               "suggest_mode": "always",
                               "pre_filter": "reverse",
                               "post_filter": "reverse"
                           }
                       ]
                   }
               }
           }
       }
   }
}

Obtener sugerencias de la aplicación

Para obtener sugerencias de Elasticsearch, estamos agregando una API de backend que el cliente puede consumir en /api/suggest. Esta nueva API llama a Elasticsearch, ejecuta la plantilla de búsqueda y transmite la búsqueda para la que deseas sugerencias, luego devuelve una sugerencia de búsqueda. La API de backend nos permite reducir la complejidad en la parte de front end.

client.searchTemplate({
       index: "suggest",
       id: 'did-you-mean-template',
       params: {
           query_string: req.body.query
       }
   })

Por ejemplo, si la búsqueda es "atavoces", la API devolverá la sugerencia "altavoces". Esto se basa en los datos ingeridos previamente que contienen las búsquedas más populares. La API de sugerencia devolverá un término que sea el más cercano sintácticamente a la búsqueda. 

Agregar "¿Quiso decir?" a la página de resultados

Ahora podemos agregar la característica "¿Quiso decir?" en la aplicación de front end. Para eso vamos a seguir trabajando en la misma aplicación React que usamos para la parte de sugerencias específicas. 

La nueva API que agregamos se puede consumir desde la aplicación React y mostrar una sugerencia en caso de que no haya resultados para la búsqueda actual. 

La idea aquí es obtener una sugerencia para cada búsqueda ingresada por el usuario. Si no hay ningún resultado, el usuario verá una sugerencia. También son posibles implementaciones alternativas: Puedes mostrar sugerencias en caso de que haya pocos resultados, o puedes ejecutar la sugerencia automáticamente en lugar de la búsqueda de un usuario.

En nuestra aplicación, tenemos un componente de React llamado SearchResults que muestra nuestros resultados de búsqueda. Allí podemos agregar una función que obtenga la sugerencia de nuestra API de backend /es/api/suggest.

const fetchDidYouMeanSuggestion = async (query) => {
   const response = await fetch('/api/did_you_mean', {
       method: 'POST',
       headers: {
           Accept: 'application/json, text/plain, */*',
           'Content-Type': 'application/json',
       },
       body: JSON.stringify(query)
   })
   const body = await response.json();
   if (response.status !== 200) throw Error(body.message);
   return body;
}

Luego, a medida que cambia la consulta, de acuerdo con el refinamiento del usuario, puedes actualizar la sugerencia llamando a la API:

   // Get search params from dom router
   const [searchParams] = useSearchParams();
 
   useEffect(() => {
       // When the searchParams contains a query
       if (searchParams.get('q')) {
           // Set query for Search UI - Run the search
           setSearchTerm(searchParams.get('q'))
           // Fetch suggestion from backend API
           fetchDidYouMeanSuggestion({ query: searchParams.get('q') }).then(res => {
               setSuggestion(res.body?.suggest?.simple_phrase[0]?.options[0]?.text)
           })
               .catch(err => console.log(err));
       }
  }, [searchParams]);

Finalmente, mostrar la sugerencia en caso de que no haya resultado para la búsqueda del usuario:

{wasSearched && totalResults == 0 && <span>No results to show{suggestion ? <>, did you mean <span style={{ cursor: "pointer", color: "blue" }} onClick={() => navigateSuggest(suggestion)}>{suggestion}</span>?</> : "."}</span>}

resultado final se ve así:

Video thumbnail

Conclusión

En esta publicación de blog, aprendiste cómo crear fácilmente características de "¿Quiso decir?" y sugerencias específicas con Enterprise Search de Elastic. Estas características se pueden integrar fácilmente en su experiencia de búsqueda existente para que tus usuarios puedan encontrar lo que buscan más rápido. Si deseas revisar el código utilizado para crear estos ejemplos, búscala en este repositorio de GitHub.

Brindar una experiencia de búsqueda moderna es fundamental para los sitios web de comercio electrónico y para muchos otros casos de uso, como la atención al cliente, la búsqueda en sitios web, la búsqueda interna en el lugar de trabajo, y las aplicaciones de búsqueda personalizadas. Se pueden seguir los pasos de esta publicación de blog para acelerar la creación de una mejor experiencia de búsqueda para todos tus usuarios finales.