Solución de problemas de los filtros de colección de OData en Azure AI Search
Para filtrar por los campos de colección en Azure AI Search, puede usar los operadores any
y all
junto con expresiones lambda. Una expresión lambda es un subfiltro que se aplica a cada elemento de una colección.
No todas las características de las expresiones de filtro están disponibles dentro de una expresión lambda. Las características disponibles difieren en función del tipo de datos del campo de colección que se quiere filtrar. Esto puede producir un error si se intenta usar una característica en una expresión lambda que no se admite en ese contexto. Si estos errores se producen al intentar escribir un filtro complejo sobre campos de colección, este artículo le ayudará a solucionar el problema.
Errores de filtro de colección comunes
En la tabla siguiente se enumeran los errores que pueden surgir al intentar ejecutar un filtro de colección. Estos errores se producen cuando se usa una característica de las expresiones de filtro que no se admite dentro de una expresión lambda. Cada error proporciona instrucciones sobre cómo puede volver a escribir el filtro para evitar el error. En la tabla también se incluye un vínculo a la sección correspondiente de este artículo en la que se proporciona más información sobre cómo evitar este error.
Mensaje de error | Situación | Detalles |
---|---|---|
La función ismatch no tiene parámetros enlazados a la variable de intervalo 's'. Dentro de las expresiones lambda solo se admiten referencias de campo enlazadas ("any" o "all"). Sin embargo, puede cambiar el filtro para que la función ismatch esté fuera de la expresión lambda e inténtelo de nuevo. |
Uso de search.ismatch o search.ismatchscoring dentro de una expresión lambda |
Reglas de filtrado de colecciones complejas |
Expresión lambda no válida. Se ha encontrado una prueba de igualdad o desigualdad cuando se esperaba lo contrario en una expresión lambda que recorre en iteración un campo de tipo Collection(Edm.String). En el caso de "any", use expresiones con los formatos "x eq y" o "search.in(...)". En cuanto a "all", use expresiones con los formatos "x ne y", "not (x eq y)" o "not search.in(...)". | Filtrado por un campo de tipo Collection(Edm.String) |
Reglas de filtrado de colecciones de cadenas |
Expresión lambda no válida. Se ha encontrado un formato de expresión booleana compleja no admitido. En el caso de "any", use expresiones que sean "OR de AND", también conocidas como forma normal disyuntiva. Por ejemplo: (a and b) or (c and d) donde a, b, c y d son subexpresiones de comparación o igualdad. En cuanto a "all", use expresiones que sean "AND de OR", también conocidas como forma normal conjuntiva. Por ejemplo: (a or b) and (c or d) donde a, b, c y d son subexpresiones de comparación o desigualdad. Ejemplos de expresiones de comparación: "x gt 5", "x le 2". Ejemplo de una expresión de igualdad: "x eq 5". Ejemplo de una expresión de desigualdad: "x ne 5". |
Filtrado por campos de tipo Collection(Edm.DateTimeOffset) , Collection(Edm.Double) , Collection(Edm.Int32) o Collection(Edm.Int64) |
Reglas de filtrado de colecciones comparables |
Expresión lambda no válida. Se ha encontrado un uso no admitido de geo.distance() o geo.intersects() en una expresión lambda que recorre en iteración un campo de tipo Collection(Edm.GeographyPoint). En el caso de "any", asegúrese de comparar geo.distance() con los operadores "lt" o "le", y de que el uso de geo.intersects() no sea negativo. Para "all", asegúrese de comparar geo.distance() con los operadores "gt" o "ge", y de que el uso de geo.intersects() sea negativo. | Filtrado por un campo de tipo Collection(Edm.GeographyPoint) |
Reglas de filtrado para colecciones GeographyPoint |
Expresión lambda no válida. No se admiten expresiones booleanas complejas en las expresiones lambda que recorren en iteración campos de tipo Collection(Edm.GeographyPoint). Para ''any'', una las subexpresiones con ''or''; no se admite ''and''. Para ''all'', una subexpresiones con ''and''; no se admite ''o''. | Filtrado por campos de tipo Collection(Edm.String) o Collection(Edm.GeographyPoint) |
Reglas de filtrado de colecciones de cadenas Reglas de filtrado para colecciones GeographyPoint |
Expresión lambda no válida. Se ha encontrado un operador de comparación (uno de "lt", "le", "gt" o "ge"). Solo se permiten operadores de igualdad en expresiones lambda que recorren en iteración los campos de tipo Collection(Edm.String). En el caso de "any", use expresiones con el formato "x eq y". En cuanto a "all", use expresiones con los formatos "x ne y" o "not (x eq y)". | Filtrado por un campo de tipo Collection(Edm.String) |
Reglas de filtrado de colecciones de cadenas |
Procedimientos para escribir filtros de colección válidos
Las reglas para escribir filtros de colección válidos son diferentes para cada tipo de datos. En las secciones siguientes se describen las reglas mediante ejemplos de las características de filtro que se admiten y las que no:
- Reglas de filtrado de colecciones de cadenas
- Reglas de filtrado de colecciones booleanas
- Reglas de filtrado para colecciones GeographyPoint
- Reglas de filtrado de colecciones comparables
- Reglas de filtrado de colecciones complejas
Reglas de filtrado de colecciones de cadenas
Dentro de las expresiones lambda para colecciones de cadenas, los únicos operadores de comparación que se pueden usar son eq
y ne
.
Nota:
Azure AI Search no admite los operadores lt
/le
/gt
/ge
para las cadenas, ni dentro ni fuera de una expresión lambda.
El cuerpo de una expresión any
solo se puede probar para igualdad, mientras el cuerpo de una expresión all
solo se puede probar para la desigualdad.
También se pueden combinar varias expresiones a través de or
en el cuerpo de any
, y a través de and
en el cuerpo de all
. Como la función search.in
equivale a combinar comprobaciones de igualdad con or
, también se permite en el cuerpo de una expresión any
. Por el contrario, not search.in
se permite en el cuerpo de una expresión all
.
Por ejemplo, se permiten estas expresiones:
tags/any(t: t eq 'books')
tags/any(t: search.in(t, 'books, games, toys'))
tags/all(t: t ne 'books')
tags/all(t: not (t eq 'books'))
tags/all(t: not search.in(t, 'books, games, toys'))
tags/any(t: t eq 'books' or t eq 'games')
tags/all(t: t ne 'books' and not (t eq 'games'))
Mientras que estas expresiones no se permiten:
tags/any(t: t ne 'books')
tags/any(t: not search.in(t, 'books, games, toys'))
tags/all(t: t eq 'books')
tags/all(t: search.in(t, 'books, games, toys'))
tags/any(t: t eq 'books' and t ne 'games')
tags/all(t: t ne 'books' or not (t eq 'games'))
Reglas de filtrado de colecciones booleanas
El tipo Edm.Boolean
solo admite los operadores eq
y ne
. Por tanto, no tiene mucho sentido permitir la combinación de estas cláusulas que comprueban la misma variable de rango con and
/or
, ya que eso siempre produciría tautologías o contradicciones.
Estos son algunos ejemplos de filtros permitidos en colecciones booleanas:
flags/any(f: f)
flags/all(f: f)
flags/any(f: f eq true)
flags/any(f: f ne true)
flags/all(f: not f)
flags/all(f: not (f eq true))
A diferencia de las colecciones de cadenas, las booleanas no tienen ningún límite con respecto a qué operador se puede usar en cada tipo de expresión lambda. Tanto eq
como ne
se pueden usar en el cuerpo de any
o all
.
Para las colecciones booleanas no se permiten expresiones como las siguientes:
flags/any(f: f or not f)
flags/any(f: f or f)
flags/all(f: f and not f)
flags/all(f: f and f eq true)
Reglas de filtrado para colecciones GeographyPoint
Los valores de tipo Edm.GeographyPoint
en una colección no se pueden comparar directamente entre sí. En su lugar, se deben usar como parámetros de las funciones geo.distance
y geo.intersects
. A su vez, la función geo.distance
se debe comparar con un valor de distancia mediante uno de los operadores de comparación lt
, le
, gt
o ge
. Estas reglas también se aplican a campos Edm.GeographyPoint que no son de colección.
Al igual que las colecciones de cadenas, las colecciones Edm.GeographyPoint
tienen algunas reglas sobre cómo se pueden usar y combinar las funciones geoespaciales en los diferentes tipos de expresiones lambda:
- Qué operadores de comparación se pueden usar con la función
geo.distance
depende del tipo de expresión lambda. Paraany
, solo puede usarlt
ole
. Paraall
, solo puede usargt
oge
. Puede negar expresiones que implicangeo.distance
, pero tiene que cambiar el operador de comparación (geo.distance(...) lt x
se convierte ennot (geo.distance(...) ge x)
ygeo.distance(...) le x
se convierte ennot (geo.distance(...) gt x)
). - En el cuerpo de una expresión
all
, la funcióngeo.intersects
debe ser negativa. Por el contrario, en el cuerpo de una expresiónany
, la funcióngeo.intersects
no debe ser negativa. - En el cuerpo de
any
, las expresiones geoespaciales se pueden combinar medianteor
. En el cuerpo deall
, ese tipo de expresiones se pueden combinar medianteand
.
Las limitaciones anteriores existen por motivos similares a la limitación de igualdad y desigualdad en las colecciones de cadenas. En Descripción de los filtros de colección de OData en Azure AI Search se explican estos motivos con mayor profundidad.
Estos son algunos ejemplos de filtros permitidos en colecciones Edm.GeographyPoint
:
locations/any(l: geo.distance(l, geography'POINT(-122 49)') lt 10)
locations/any(l: not (geo.distance(l, geography'POINT(-122 49)') ge 10) or geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))
locations/all(l: geo.distance(l, geography'POINT(-122 49)') ge 10 and not geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))
En las colecciones Edm.GeographyPoint
no se permiten expresiones como las siguientes:
locations/any(l: l eq geography'POINT(-122 49)')
locations/any(l: not geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))
locations/all(l: geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))
locations/any(l: geo.distance(l, geography'POINT(-122 49)') gt 10)
locations/all(l: geo.distance(l, geography'POINT(-122 49)') lt 10)
locations/any(l: geo.distance(l, geography'POINT(-122 49)') lt 10 and geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))
locations/all(l: geo.distance(l, geography'POINT(-122 49)') le 10 or not geo.intersects(l, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))'))
Reglas de filtrado de colecciones comparables
Esta sección se aplica a todos los tipos de datos siguientes:
Collection(Edm.DateTimeOffset)
Collection(Edm.Double)
Collection(Edm.Int32)
Collection(Edm.Int64)
Los tipos como Edm.Int32
y Edm.DateTimeOffset
admiten los seis operadores de comparación: eq
, ne
, lt
, le
, gt
y ge
. Las expresiones lambda de colecciones de estos tipos pueden incluir expresiones simples en las que se use cualquiera de estos operadores. Esto se aplica a any
y all
. Por ejemplo, se permiten estos filtros:
ratings/any(r: r ne 5)
dates/any(d: d gt 2017-08-24T00:00:00Z)
not margins/all(m: m eq 3.5)
Pero existen limitaciones con respecto a cómo se pueden combinar estas expresiones de comparación en expresiones más complejas dentro de una expresión lambda:
- Reglas para
any
:Las expresiones de desigualdad simples no se pueden combinar de forma útil con otras expresiones. Por ejemplo, se permite esta expresión:
ratings/any(r: r ne 5)
pero no esta expresión:
ratings/any(r: r ne 5 and r gt 2)
y aunque se permite esta expresión, no es útil porque las condiciones se superponen:
ratings/any(r: r ne 5 or r gt 7)
Las expresiones de comparación simples que contengan
eq
,lt
,le
,gt
oge
se pueden combinar conand
/or
. Por ejemplo:ratings/any(r: r gt 2 and r le 5)
ratings/any(r: r le 5 or r gt 7)
Las expresiones de comparación combinadas con
and
(conjunciones) se pueden combinar aún más medianteor
. En lógica booleana, este formato se conoce como "forma normal disyuntiva" (DNF). Por ejemplo:ratings/any(r: (r gt 2 and r le 5) or (r gt 7 and r lt 10))
- Reglas para
all
:Las expresiones de igualdad simples no se pueden combinar de forma útil con ninguna otra expresión. Por ejemplo, se permite esta expresión:
ratings/all(r: r eq 5)
pero no esta expresión:
ratings/all(r: r eq 5 or r le 2)
y aunque se permite esta expresión, no es útil porque las condiciones se superponen:
ratings/all(r: r eq 5 and r le 7)
Las expresiones de comparación simples que contengan
ne
,lt
,le
,gt
oge
se pueden combinar conand
/or
. Por ejemplo:ratings/all(r: r gt 2 and r le 5)
ratings/all(r: r le 5 or r gt 7)
Las expresiones de comparación combinadas con
or
(disyunciones) se pueden combinar aún más medianteand
. En lógica booleana, este formato se conoce como "forma normal conjuntiva" (CNF). Por ejemplo:ratings/all(r: (r le 2 or gt 5) and (r lt 7 or r ge 10))
Reglas de filtrado de colecciones complejas
Las expresiones lambda sobre colecciones complejas admiten una sintaxis mucho más flexible que las expresiones lambda sobre colecciones de tipos primitivos. Dentro de una expresión lambda puede usar cualquier construcción de filtro que se pueda usar fuera de ella, con solo dos excepciones.
En primer lugar, las funciones search.ismatch
y search.ismatchscoring
no se admiten dentro de las expresiones lambda. Para más información, consulte Descripción de los filtros de colección de OData en Azure AI Search.
En segundo lugar, los campos de referencia que no están enlazados a la variable de rango (denominados variables independientes) no están permitidos. Por ejemplo, fíjese en las dos siguientes expresiones de filtro de OData equivalentes:
stores/any(s: s/amenities/any(a: a eq 'parking')) and details/margin gt 0.5
stores/any(s: s/amenities/any(a: a eq 'parking' and details/margin gt 0.5))
Se permite la primera expresión, mientras que el segundo formulario se rechaza porque details/margin
no está enlazado a la variable de intervalo s
.
Esta regla también se extiende a las expresiones que tienen variables enlazadas en un ámbito externo. Estas variables son independientes con respecto al ámbito en el que aparecen. Por ejemplo, se permite la primera expresión, mientras que la segunda expresión equivalente no, porque s/name
es independiente con respecto al ámbito de la variable de rango a
:
stores/any(s: s/amenities/any(a: a eq 'parking') and s/name ne 'Flagship')
stores/any(s: s/amenities/any(a: a eq 'parking' and s/name ne 'Flagship'))
Esta limitación no debería ser un problema en la práctica, ya que siempre se pueden construir filtros de forma que las expresiones lambda solo contengan variables enlazadas.
Hoja de referencia rápida de reglas de filtro de colección
En la tabla siguiente se resumen las reglas para construir filtros válidos para cada tipo de datos de la colección.
Tipo de datos | Características que se permiten en expresiones lambda con any |
Características que se permiten en expresiones lambda con all |
---|---|---|
Collection(Edm.ComplexType) |
Todo excepto search.ismatch y search.ismatchscoring |
Iguales |
Collection(Edm.String) |
Comparaciones con eq o search.in Combinación de las subexpresiones con or |
Comparaciones con ne o not search.in() Combinación de las subexpresiones con and |
Collection(Edm.Boolean) |
Comparaciones con eq o ne |
Iguales |
Collection(Edm.GeographyPoint) |
Uso de geo.distance con lt o le geo.intersects Combinación de las subexpresiones con or |
Uso de geo.distance con gt o ge not geo.intersects(...) Combinación de las subexpresiones con and |
Collection(Edm.DateTimeOffset) , Collection(Edm.Double) , Collection(Edm.Int32) , Collection(Edm.Int64) |
Comparaciones mediante eq , ne , lt , gt , le o ge Combinación de las comparaciones con otras subexpresiones mediante or Combinación de las comparaciones, excepto ne con otras subexpresiones mediante and Expresiones que utilizan combinaciones de and y or en el formulario normal disyuntivo (DNF) |
Comparaciones mediante eq , ne , lt , gt , le o ge Combinación de las comparaciones con otras subexpresiones mediante and Combinación de las comparaciones, excepto eq con otras subexpresiones mediante or Expresiones que utilizan combinaciones de and y or en el formulario normal conjuntivo (CNF) |
Para obtener ejemplos de cómo crear filtros válidos para cada caso, vea Procedimientos para escribir filtros de colección válidos.
Si escribe filtros con frecuencia y conocer las reglas de los primeros principios le resultaría más útil que memorizarlos, consulte Descripción de los filtros de colección de OData en Azure AI Search.
Pasos siguientes
- Descripción 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 Azure AI Search
- Referencia de la sintaxis de las expresiones de OData para Azure AI Search
- Buscar documentos (API REST de Azure AI Search)