Compartir vía


Búsqueda de términos parciales y patrones con caracteres especiales (guiones, carácter comodín, expresión regular y patrones)

Una búsqueda de términos parciales hace referencia a las consultas que se componen de fragmentos de términos, en las que en lugar de un término completo, es posible que tenga solo el inicio, el centro o el final del mismo (a veces se denominan consultas de prefijo, infijo o sufijo). Una búsqueda de términos parciales podría incluir una combinación de fragmentos, a menudo con caracteres especiales, como guiones o barras diagonales, que forman parte de la cadena de consulta. Entre los casos de uso comunes se incluyen partes de un número de teléfono, una dirección URL, códigos o palabras compuestas con guiones.

Los términos parciales y los caracteres especiales pueden ser problemáticos si el índice no tiene un token que represente el fragmento de texto que desea buscar. Durante la fase de análisis léxico de la indexación de palabra clave (suponiendo que se usa el analizador estándar predeterminado), se descartan los caracteres especiales, se dividen las palabras compuestas y se eliminan los espacios en blanco. Si busca un fragmento de texto modificado durante el análisis léxico, se produce un error en la consulta porque no se encuentra ninguna coincidencia. Observe este ejemplo: un número de teléfono como +1 (425) 703-6214 (tokenizado como "1", "425", "703", "6214") no se mostrará en una consulta "3-62" porque ese contenido no existe realmente en el índice.

La solución consiste en invocar un analizador durante la indexación que conserve una cadena completa, incluidos espacios y caracteres especiales, si es necesario, para que pueda incluir los espacios y caracteres en la cadena de consulta. Una cadena completa sin tokens permite la coincidencia de patrones para las consultas de tipo "empieza con" o "finaliza con", en las que el patrón proporcionado se puede evaluar con respecto a un término que no se transforma por el análisis léxico.

Si necesita admitir escenarios de búsqueda que llaman a contenido analizado y no analizado, considere la posibilidad de crear dos campos en el índice, uno para cada escenario. Uno de ellos se somete a un análisis léxico. El segundo campo almacena una cadena intacta gracias a un analizador de conservación de contenido que emite tokens de cadena completa para lograr una coincidencia de patrones.

Azure AI Search examina si hay términos con tokens completos en el índice y no encontrará una coincidencia en un término parcial a menos que incluya operadores de marcadores de posición de caracteres comodín (* y ?), o aplique un formato de expresión regular a la consulta.

Los términos parciales se especifican mediante estas técnicas:

  • Las consultas de expresiones regulares pueden ser cualquier expresión regular que sea válida en Apache Lucene.

  • Los operadores de caracteres comodín con coincidencia de prefijos hacen referencia a un patrón reconocido generalmente que incluye el principio de un término, seguido de los operadores de sufijo * o ?, como la coincidencia de search=cap* en "Cap'n Jack's Waterfront Inn" o "Highline Capital". La coincidencia de prefijos es compatible con la sintaxis de consulta de Lucene simple y completa.

  • El carácter comodín con coincidencia de infijos y sufijos coloca los operadores * y ? dentro o al principio de un término y requiere la sintaxis de expresiones regulares (donde la expresión se incluye entre barras diagonales). Por ejemplo, la cadena de consulta (search=/.*numeric.*/) devuelve resultados en "alphanumeric" y "alphanumerical" como coincidencias de sufijo e infijo.

Para la búsqueda con expresiones regulares, carácter comodín y aproximada, los analizadores no se usan en el momento de la consulta. En el caso de estos formularios de consulta, en los que el analizador detecta por la presencia de operadores y delimitadores, la cadena de consulta se pasa al motor sin análisis léxico. En estos formularios de consulta, el analizador especificado en el campo se omite.

Nota:

Cuando una cadena de consulta parcial incluye caracteres, como barras en un fragmento de dirección URL, puede que tenga que agregar caracteres de escape. En JSON, una barra diagonal / se escapa con una barra diagonal inversa \. Así, search=/.*microsoft.com\/azure\/.*/ es la sintaxis del fragmento de dirección URL "microsoft.com/azure/".

Solución de problemas de búsqueda de términos parciales o patrones

Si necesita buscar en fragmentos, patrones o caracteres especiales, puede invalidar el analizador predeterminado con un analizador personalizado que funcione con reglas de tokenización más sencillas y conserve toda la cadena en el índice.

El enfoque tiene este aspecto:

  1. Defina otro campo para almacenar una versión intacta de la cadena (suponiendo que desee texto analizado y no analizado en el momento de la consulta)
  2. Evalúe y elija entre los distintos analizadores que emiten tokens en el nivel de granularidad adecuado.
  3. Asigne el analizador al campo.
  4. Compile y pruebe el índice.

1. Creación de un campo dedicado

Los analizadores determinan cómo se acortan los términos en un índice. Dado que los analizadores se asignan por campo, puede crear campos en el índice para optimizar los distintos escenarios. Por ejemplo, puede definir "featureCode" y "featureCodeRegex" para admitir la búsqueda de texto completo normal en el primero y la coincidencia de patrones avanzada en el segundo. Los analizadores asignados a cada campo determinan cómo se acorta el contenido de cada campo en el índice.

{
  "name": "featureCode",
  "type": "Edm.String",
  "retrievable": true,
  "searchable": true,
  "analyzer": null
},
{
  "name": "featureCodeRegex",
  "type": "Edm.String",
  "retrievable": true,
  "searchable": true,
  "analyzer": "my_custom_analyzer"
},

2. Establecimiento de un analizador

Al elegir un analizador que produce tokens de términos completos, los siguientes analizadores son opciones comunes:

Analyzer Comportamientos
Analizadores de idiomas Conserva los guiones en palabras compuestas o cadenas, mutaciones vocálicas y formas verbales. Si los patrones de consulta incluyen guiones, el uso de un analizador de idioma puede ser suficiente.
keyword El contenido de todo el campo se acorta para pasar a ser un solo término.
whitespace Solo se separa en espacios en blanco. Los términos que incluyen guiones u otros caracteres se tratan como un solo token.
analizador personalizado (Recomendado) La creación de un analizador personalizado le permite especificar el filtro de tokens y el tokenizador. Los analizadores anteriores deben usarse tal cual. Un analizador personalizado le permite elegir los filtros de token y los tokenizadores que quiere usar.

Una combinación recomendada es el tokenizador de palabras claves con un filtro de tokens en minúsculas. Por sí solo, el analizador de palabras clave integrado no pasa a minúsculas ningún texto en mayúsculas, lo que puede provocar errores en las consultas. Un analizador personalizado le ofrece un mecanismo para agregar el filtro de tokens en minúsculas.

Si usa un cliente REST, puede agregar la llamada de REST del analizador de pruebas para inspeccionar la salida con tokens.

El índice debe existir en el servicio de búsqueda, pero puede estar vacío. Si se da una situación en que tiene un índice y un campo que contiene guiones o términos parciales, puede probar varios analizadores en términos específicos para ver qué tokens se emiten.

  1. En primer lugar, compruebe el analizador estándar para ver cómo se acortan los términos de forma predeterminada.

    {
    "text": "SVP10-NOR-00",
    "analyzer": "standard"
    }
    
  2. Evalúe la respuesta para ver cómo se acorta el texto en el índice. Observe cómo cada término está en minúsculas, sin guiones y las subcadenas divididas en tokens individuales. Solo las consultas que coincidan con estos tokens devolverán este documento en los resultados. Se producirá un error en una consulta que incluya "10-NOR".

    {
        "tokens": [
            {
                "token": "svp10",
                "startOffset": 0,
                "endOffset": 5,
                "position": 0
            },
            {
                "token": "nor",
                "startOffset": 6,
                "endOffset": 9,
                "position": 1
            },
            {
                "token": "00",
                "startOffset": 10,
                "endOffset": 12,
                "position": 2
            }
        ]
    }
    
  3. Ahora, modifique la solicitud para usar el analizador whitespace o keyword:

    {
    "text": "SVP10-NOR-00",
    "analyzer": "keyword"
    }
    
  4. Esta vez, la respuesta se compone de un solo token escrito en mayúsculas con guiones que se mantienen como parte de la cadena. Si necesita realizar una búsqueda en un patrón o un término parcial, como "10-NOR", el motor de consultas ahora cuenta con la base para encontrar una coincidencia.

    {
    
        "tokens": [
            {
                "token": "SVP10-NOR-00",
                "startOffset": 0,
                "endOffset": 12,
                "position": 0
            }
        ]
    }
    

Importante

Tenga en cuenta que los analizadores de consultas a menudo usan términos en minúsculas en una expresión de búsqueda al compilar el árbol de consulta. Si usa un analizador que no introduce las entradas de texto en minúsculas durante la indexación y no obtiene los resultados esperados, este podría ser el motivo. La solución consiste en agregar un filtro de tokens en minúsculas, tal como se describe en la sección "Uso de analizadores personalizados" más adelante.

3. Configuración de un analizador

Tanto si está evaluando analizadores como si avanza con una configuración concreta, tendrá que especificar el analizador en la definición del campo y, posiblemente, deberá configurar el analizador en sí si no usa ningún analizador integrado. Al intercambiar analizadores, normalmente debe volver a generar el índice (quitarlo, volverlo a crear y cargarlo de nuevo).

Uso de analizadores integrados

Los analizadores integrados se pueden especificar por su nombre en la propiedad analyzer de una definición de campo, sin necesidad de establecer configuración adicional en el índice. En el ejemplo siguiente se muestra cómo debería establecer el analizador whitespace en un campo.

Para otros escenarios y más información sobre otros analizadores integrados, consulte Analizadores integrados.

    {
      "name": "phoneNumber",
      "type": "Edm.String",
      "key": false,
      "retrievable": true,
      "searchable": true,
      "analyzer": "whitespace"
    }

Uso de analizadores personalizados

Si usa un analizador personalizado, debe definirlo en el índice con una combinación definida por el usuario de tokenizador, filtro de tokens y posibles valores de configuración. A continuación, haga referencia a él en una definición de campo, tal como lo haría con un analizador integrado.

Cuando el objetivo sea la tokenización de términos completos, le recomendamos que use un analizador personalizado que conste de un tokenizador de palabras clave y un filtro de tokens en minúsculas.

  • El tokenizador de palabras clave crea un solo token para todo el contenido de un campo.
  • El filtro de tokens en minúsculas transforma las letras mayúsculas en texto en minúsculas. Los analizadores de consultas suelen convertir en minúsculas cualquier entrada de texto en mayúsculas. El uso de minúsculas homogeneiza las entradas con los términos acortados.

En el ejemplo siguiente se muestra un analizador personalizado que proporciona el tokenizador de palabras clave y un filtro de tokens en minúsculas.

{
"fields": [
  {
    "name": "accountNumber",
    "analyzer":"myCustomAnalyzer",
    "type": "Edm.String",
    "searchable": true,
    "filterable": true,
    "retrievable": true,
    "sortable": false,
    "facetable": false
  }
],

"analyzers": [
  {
    "@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
    "name":"myCustomAnalyzer",
    "charFilters":[],
    "tokenizer":"keyword_v2",
    "tokenFilters":["lowercase"]
  }
],
"tokenizers":[],
"charFilters": [],
"tokenFilters": []
}

Nota:

El sistema conoce el tokenizador keyword_v2 y el filtro de tokens lowercase y estos utilizan sus configuraciones predeterminadas, por lo que puede hacer referencia a ellos por su nombre sin tener que definirlos primero.

4. Compilación y prueba

Una vez que haya definido un índice con analizadores y definiciones de campo que admitan su escenario, cargue documentos que tengan cadenas representativas para poder probar consultas de cadenas parciales.

Use un cliente de REST para consultar términos parciales y caracteres especiales descritos en este artículo.

La lógica se explicó en las secciones anteriores. En esta sección se explican las API que debe llamar al probar la solución.

  • Eliminación de índice quita un índice existente con el mismo nombre para que pueda volver a crearlo.

  • Creación de índice crea la estructura de índice en el servicio de búsqueda, incluidas las definiciones y los campos, así como una especificación, del analizador.

  • Carga de documentos importa documentos que tienen la misma estructura que el índice, así como contenido que se puede buscar. Después de este paso, el índice está listo para realizar consultas o pruebas.

  • El analizador de pruebas se presentó en Establecimiento de un analizador. Pruebe algunas de las cadenas del índice usando varios analizadores para entender cómo se acortan los términos.

  • Búsqueda de documentos explica cómo construir una solicitud de consulta mediante una sintaxis simple o la sintaxis de Lucene completa para caracteres comodín y expresiones regulares.

    En el caso de las consultas de términos parciales, como la consulta de "3-6214" para encontrar una coincidencia en "+ 1 (425) 703-6214", puede usar la sintaxis simple: search=3-6214&queryType=simple.

    En el caso de las consultas de infijos y de sufijos, como consultar "num" o "numéric" para encontrar una coincidencia en "alfanumérico", use la sintaxis completa de Lucene y una expresión regular: search=/.*num.*/&queryType=full

Optimización de consultas de prefijo y sufijo

La coincidencia de prefijos y sufijos mediante el analizador predeterminado requiere características de consulta adicionales. Los prefijos requieren búsqueda con caracteres comodín y los sufijos requieren búsqueda de expresiones regulares. Ambas características pueden reducir el rendimiento de las consultas.

En el ejemplo siguiente se agrega un EdgeNGramTokenFilter para que el prefijo o sufijo coincida con más rapidez. Los tokens se generan en combinaciones de 2 a 25 caracteres que incluyen caracteres. Este es un ejemplo de progresión de dos a siete tokens: MS, MSFT, MSFT, MSFT/, MSFT/S, MSFT/SQ, MSFT/SQL. EdgeNGramTokenFilter requiere un side parámetro que determina a qué lado de las combinaciones de caracteres de cadena se generan. Use front para las consultas de prefijo y back para las consultas de sufijo.

La tokenización adicional da como resultado un índice mayor. Si tiene capacidad suficiente para alojar el índice más grande, este enfoque con su tiempo de respuesta más rápido podría ser la mejor solución.

{
"fields": [
  {
    "name": "accountNumber_prefix",
    "indexAnalyzer": "ngram_front_analyzer",
    "searchAnalyzer": "keyword",
    "type": "Edm.String",
    "searchable": true,
    "filterable": false,
    "retrievable": true,
    "sortable": false,
    "facetable": false
  },
  {
    "name": "accountNumber_suffix",
    "indexAnalyzer": "ngram_back_analyzer",
    "searchAnalyzer": "keyword",
    "type": "Edm.String",
    "searchable": true,
    "filterable": false,
    "retrievable": true,
    "sortable": false,
    "facetable": false
  }
],

"analyzers": [
  {
    "@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
    "name":"ngram_front_analyzer",
    "charFilters":[],
    "tokenizer":"keyword_v2",
    "tokenFilters":["lowercase", "front_edgeNGram"]
  },
  {
    "@odata.type":"#Microsoft.Azure.Search.CustomAnalyzer",
    "name":"ngram_back_analyzer",
    "charFilters":[],
    "tokenizer":"keyword_v2",
    "tokenFilters":["lowercase", "back_edgeNGram"]
  }
],
"tokenizers":[],
"charFilters": [],
"tokenFilters": [
  {
    "@odata.type":"#Microsoft.Azure.Search.EdgeNGramTokenFilterV2",
    "name":"front_edgeNGram",
    "minGram": 2,
    "maxGram": 25,
    "side": "front"
  },
  {
    "@odata.type":"#Microsoft.Azure.Search.EdgeNGramTokenFilterV2",
    "name":"back_edgeNGram",
    "minGram": 2,
    "maxGram": 25,
    "side": "back"
  }
]
}

Para buscar números de cuenta que empiecen por 123, podemos usar la siguiente consulta:

{
  "search": "123",
  "searchFields": "accountNumber_prefix"
}

Para buscar números de cuenta que terminan con 456, podemos usar la consulta siguiente:

{
  "search": "456",
  "searchFields": "accountNumber_suffix"
}

Pasos siguientes

En este artículo se explica cómo contribuyen ambos analizadores a los problemas de consultas y a cómo solucionarlos. A continuación, veremos cómo afectan los analizadores a la indexación y el procesamiento de consultas.