Compartir vía


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

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. Para any, solo puede usar lt o le. Para all, solo puede usar gt o ge. Puede negar expresiones que implican geo.distance, pero tiene que cambiar el operador de comparación (geo.distance(...) lt x se convierte en not (geo.distance(...) ge x) y geo.distance(...) le x se convierte en not (geo.distance(...) gt x)).
  • En el cuerpo de una expresión all, la función geo.intersects debe ser negativa. Por el contrario, en el cuerpo de una expresión any, la función geo.intersects no debe ser negativa.
  • En el cuerpo de any, las expresiones geoespaciales se pueden combinar mediante or. En el cuerpo de all, ese tipo de expresiones se pueden combinar mediante and.

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 o ge se pueden combinar con and/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 mediante or. 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 o ge se pueden combinar con and/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 mediante and. 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:

  1. stores/any(s: s/amenities/any(a: a eq 'parking')) and details/margin gt 0.5
  2. 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:

  1. stores/any(s: s/amenities/any(a: a eq 'parking') and s/name ne 'Flagship')
  2. 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