Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Nota:
Búsqueda de Azure AI está disponible a través del portal de Azure, las API REST y los SDK de Azure. También respalda Foundry IQ, la capa de conocimiento administrada que transforma el contenido empresarial en bases de conocimiento reutilizables y compatibles con permisos para agentes en el portal de Microsoft Foundry.
En este artículo se proporciona información general para los desarrolladores que escriben filtros avanzados con expresiones lambda complejas. En el artículo se explica por qué existen reglas para los filtros de recopilación mediante la exploración de cómo la Búsqueda de Azure AI ejecuta estos filtros.
Al construir un filtro en campos de colección en la Búsqueda de Azure AI, puede utilizar los any y all operadores junto con expresiones lambda. Las expresiones lambda son expresiones booleanas que hacen referencia a una variable de rango. En los filtros que usan una expresión lambda, los operadores any y all son análogos a un bucle for en la mayoría de los lenguajes de programación, con la variable de intervalo que toma el rol de variable de bucle y la expresión lambda como cuerpo del bucle. La variable de rango toma el valor "actual" de la colección durante la iteración del bucle.
Al menos, así es cómo funciona conceptualmente. En la realidad, Azure AI Search implementa los filtros de forma muy diferente a cómo funcionan los bucles de for. Idealmente, esta diferencia tendría que ser invisible para usted, pero en ciertas situaciones no lo es. El resultado final es que hay reglas que se deben seguir al escribir las expresiones lambda.
Nota:
Para obtener información sobre qué son las reglas para los filtros de colección, con ejemplos incluidos, vea Solución de problemas de filtros de colección de OData en Azure AI Search.
Por qué los filtros de colección son limitados
Hay tres motivos subyacentes por los que las características de filtro no son totalmente compatibles con todos los tipos de colecciones:
- Solo se admiten determinados operadores para determinados tipos de datos. Por ejemplo, no tiene sentido comparar los valores
truebooleanos yfalsemediante operadores de comparación comoltygt. - Búsqueda de Azure AI admite filtros correlacionados en campos de tipo
Collection(Edm.ComplexType), pero la búsqueda de texto completo en campos específicos en esos campos no es correlacionada. - Azure AI Search usa índices invertidos para ejecutar los filtros en todos los tipos de datos, incluidas las colecciones.
El primer motivo es simplemente una consecuencia de cómo se definen el lenguaje OData y el sistema de tipos EDM. Los dos últimos se explican con más detalle en el resto de este artículo.
Diferencias entre búsqueda correlacionada y no correlacionada
Cuando se aplican varios criterios de filtro sobre una colección de objetos complejos, los criterios se correlacionan porque se aplican a cada objeto de la colección. Por ejemplo, el siguiente filtro devuelve hoteles que tienen al menos una habitación deluxe con una tarifa inferior a 100:
Rooms/any(room: room/Type eq 'Deluxe Room' and room/BaseRate lt 100)
Si el filtrado fuera no correlacionado, el filtro anterior podría devolver hoteles en los que una habitación es deluxe y otra diferente tiene una tarifa base inferior a 100. Eso no tendría sentido, ya que las dos cláusulas de la expresión lambda se aplican a la misma variable de rango, es decir, room. Por este motivo estos filtros se ponen en correlación.
Pero para la búsqueda de texto completo, no hay ninguna manera para hacer referencia a una variable de rango específica. Si usa la búsqueda clasificada por campos para emitir una consulta completa de Lucene como esta:
Rooms/Type:deluxe AND Rooms/Description:"city view"
puede obtener hoteles donde una habitación sea deluxe, y en otra diferente se mencione "vistas a la ciudad" en la descripción. Por ejemplo, el documento siguiente con el Id de 1 coincidiría con la consulta:
{
"value": [
{
"Id": "1",
"Rooms": [
{ "Type": "deluxe", "Description": "Large garden view suite" },
{ "Type": "standard", "Description": "Standard city view room" }
]
},
{
"Id": "2",
"Rooms": [
{ "Type": "deluxe", "Description": "Courtyard motel room" }
]
}
]
}
El motivo es que Rooms/Type hace referencia a todos los términos analizados del campo Rooms/Type en todo el documento y lo mismo sucede con Rooms/Description, como se muestra en las tablas siguientes.
Cómo se almacena Rooms/Type para la búsqueda de texto completo:
Término en Rooms/Type |
ID de documento |
|---|---|
| de lujo | 1, 2 |
| Estándar | 1 |
Cómo se almacena Rooms/Description para la búsqueda de texto completo:
Término en Rooms/Description |
ID de documento |
|---|---|
| patio | 2 |
| ciudad | 1 |
| jardín | 1 |
| grande | 1 |
| motel | 2 |
| sala | 1, 2 |
| Estándar | 1 |
| suite | 1 |
| ver | 1 |
Por tanto, a diferencia del filtro anterior, que básicamente dice "coincidir documentos donde una habitación Type es igual a 'Deluxe Room' (habitación deluxe) y esa misma habitación tiene un valor BaseRate inferior a 100", la consulta de búsqueda dice "coincidir documentos donde Rooms/Type tiene el término 'Deluxe' y Rooms/Description tiene la frase 'City View'". En el último caso no hay ningún concepto de habitación individual cuyos campos se puedan poner en correlación.
Índices invertidos y colecciones
Es posible que observe que las expresiones lambda tienen muchas menos restricciones en colecciones complejas que en colecciones simples, como Collection(Edm.Int32) y Collection(Edm.GeographyPoint). Esta diferencia existe porque Búsqueda de Azure AI almacena colecciones complejas como colecciones reales de subdocumentos, mientras que las colecciones simples no se almacenan como colecciones en absoluto.
Por ejemplo, considere un campo de una colección de cadenas que se puede filtrar como seasons en un índice de un minorista en línea. Algunos documentos cargados en este índice podrían tener este aspecto:
{
"value": [
{
"id": "1",
"name": "Hiking boots",
"seasons": ["spring", "summer", "fall"]
},
{
"id": "2",
"name": "Rain jacket",
"seasons": ["spring", "fall", "winter"]
},
{
"id": "3",
"name": "Parka",
"seasons": ["winter"]
}
]
}
Los valores del campo seasons se almacenan en una estructura denominada índice invertido, similar a lo siguiente:
| Término | ID de documento |
|---|---|
| spring | 1, 2 |
| verano | 1 |
| caída | 1, 2 |
| winter | 2, 3 |
Esta estructura de datos está diseñada para responder a una pregunta con gran velocidad: ¿en qué documentos se muestra un término determinado? La respuesta a esta pregunta funciona más como una sencilla comprobación de igualdad que un bucle a través de una colección. De hecho, este es el motivo por el que en el caso de las colecciones de cadenas, Azure AI Search solo permite eq como un operador de comparación dentro de una expresión lambda para any.
A continuación, veremos cómo es posible combinar varias comprobaciones de igualdad en la misma variable de intervalo con or. Funciona gracias al álgebra y a la propiedad distributiva de los cuantificadores. Esta expresión:
seasons/any(s: s eq 'winter' or s eq 'fall')
equivale a:
seasons/any(s: s eq 'winter') or seasons/any(s: s eq 'fall')
y cada una de las dos subexpresiones any se puede ejecutar de forma eficaz mediante el índice invertido. Además, gracias a la ley de negación de cuantificadores, esta expresión:
seasons/all(s: s ne 'winter' and s ne 'fall')
equivale a:
not seasons/any(s: s eq 'winter' or s eq 'fall')
motivo por el que se puede usar all con ne y and.
Nota:
Aunque los detalles están fuera del ámbito de este documento, estos mismos principios también se extienden a las pruebas de distancia e intersección para colecciones de puntos geoespaciales. Por este motivo, en any:
-
geo.intersectsno se puede negar -
geo.distancese debe comparar conltole - las expresiones se deben combinar con
or, no conand
Para all se aplican las reglas inversas.
Al filtrar por colecciones de tipos de datos que admiten los operadores lt, gt, le y ge (como por ejemplo Collection(Edm.Int32)) se admite una mayor variedad de expresiones. En concreto, en and se pueden usar or y any, siempre y cuando las expresiones de comparación subyacentes se combinen en comparaciones de rango mediante and, que después se vuelven a combinar con or. Esta estructura de expresiones booleanas se denomina forma normal disyuntiva (DNF), también conocida como "OR de AND". Por el contrario, las expresiones lambda para all para estos tipos de datos deben estar en forma normal conjuntiva (CNF), también conocida como "AND de OR". Azure AI Search permite estas comparaciones de rango, ya que las puede ejecutar de forma eficaz mediante índices invertidos, al igual que puede realizar búsquedas de términos rápidas para las cadenas.
En resumen, estas son las reglas generales para lo que se permite en una expresión lambda:
- Dentro de
any, las comprobaciones positivas siempre se permiten, como las comparaciones de rango de igualdad,geo.intersects, o biengeo.distancecomparado conltole(imagine que la "proximidad" es similar a la igualdad cuando se comprueba la distancia). - Dentro de
any,orestá siempre permitido. Solo se puede usarandpara los tipos de datos que pueden expresar comprobaciones de intervalo, y solo si se usan operadores OR de AND (DNF). - Dentro de
all, se invierten las reglas. Solo se permiten comprobaciones negativas, puede usarandsiempre y solo puede usarorpara las comprobaciones de intervalo expresadas como AND de OR (CNF).
De todos modos, en la práctica estos son los tipos de filtros que es más probable que use. Pero sigue siendo útil comprender los límites de lo que es posible.
Para obtener ejemplos específicos de qué tipos de filtros se permiten y cuáles no, vea Procedimientos para escribir filtros de colección válidos.
Pasos siguientes
- Solución de problemas de los filtros de colección de OData en Azure AI Search
- Filtros de Azure AI Search
- Información general sobre el lenguaje de las expresiones de OData para Búsqueda de Azure AI
- Referencia de la sintaxis de las expresiones de OData para Búsqueda de Azure AI
- Buscar documentos (API REST de Búsqueda de Azure AI)