Condividi tramite


Risoluzione dei problemi relativi ai filtri di raccolta OData in Azure AI Search

Per usare un filtro sui campi della raccolta in Azure AI Search, è possibile usare gli operatori any e all insieme alle espressioni lambda. Un'espressione lambda è un sottofiltro applicato a ciascun elemento di una raccolta.

Non tutte le funzionalità delle espressioni di filtro sono disponibili all'interno di un'espressione lambda. Le caratteristiche disponibili variano a seconda del tipo di dati del campo di raccolta da filtrare. Ciò può comportare un errore se si tenta di usare una funzionalità in un'espressione lambda non supportata in tale contesto. Se si verificano errori di questo tipo durante il tentativo di scrivere un filtro complesso sui campi della raccolta, questo articolo consente di risolvere il problema.

Errori comuni sui filtri della raccolta

Nella tabella seguente sono elencati gli errori che possono verificarsi durante il tentativo di eseguire un filtro di raccolta. Questi errori si verificano quando si usa una funzionalità di espressioni di filtro non supportata all'interno di un'espressione lambda. Ogni errore fornisce indicazioni su come riscrivere il filtro per evitare l'errore. La tabella include anche un collegamento alla sezione pertinente di questo articolo che fornisce altre informazioni su come evitare tale errore.

Messaggio d'errore Situazione Dettagli
La funzione ismatch non ha parametri associati alla variabile di intervallo 's'. Solo i riferimenti ai campi associati sono supportati all'interno di espressioni lambda ("any" o "all"). Tuttavia, è possibile modificare il filtro in modo che la funzione ismatch si trovi all'esterno dell'espressione lambda e riprovare. Uso di search.ismatch o search.ismatchscoring all'interno di un'espressione lambda Regole per filtrare raccolte complesse
Espressione lambda non valida. È stato rilevato un test per verificarne l'uguaglianza o la disuguaglianza, in cui il contrario era previsto in un'espressione lambda che esegue l'iterazione su un campo di tipo Collection(Edm.String). Per "any", usare le espressioni nei formati "x eq y" o "search.in(...)". Per "all", usare le espressioni nei formati "x ne y", "not (x eq y)" o "not search.in(...)". Filtro in un campo di tipo Collection(Edm.String) Regole per filtrare le raccolte di stringhe
Espressione lambda non valida. Rilevata una forma non supportata di espressione booleana complessa. Per "any", usare espressioni "OR di AND", note anche come Forma normale disgiuntiva. Ad esempio: (a and b) or (c and d) dove a, b, c e d sono sottoespressioni di confronto o uguaglianza. Per "all", usare espressioni "AND di OR", note anche come Forma normale congiuntiva. Ad esempio: (a or b) and (c or d) dove a, b, c e d sono sottoespressioni di confronto o disuguaglianza. Esempi di espressioni di confronto: "x gt 5", "x le 2". Esempio di espressione di uguaglianza: "x eq 5". Esempio di espressione di disuguaglianza: "x ne 5". Filtri relativi ai campi di tipo Collection(Edm.DateTimeOffset), Collection(Edm.Double), Collection(Edm.Int32) o Collection(Edm.Int64) Regole per filtrare raccolte confrontabili
Espressione lambda non valida. È stato rilevato un uso non supportato di geo.distance() o geo.intersects() in un'espressione lambda che esegue l'iterazione su un campo di tipo Collection(Edm.GeographyPoint). Per "any", assicurarsi di confrontare geo.distance() usando gli operatori "lt" o "le" e assicurarsi che qualsiasi utilizzo di geo.intersects() non venga negato. Per "all", assicurarsi di confrontare geo.distance() usando gli operatori "gt" o "ge" e assicurarsi che tutti gli utilizzi di geo.intersects() vengano negati. Filtro in un campo di tipo Collection(Edm.GeographyPoint) Regole per filtrare le raccolte GeographyPoint
Espressione lambda non valida. Le espressioni booleane complesse non sono supportate nelle espressioni lambda che eseguano l'iterazione sui campi di tipo Collection(Edm.GeographyPoint). Per "any", unire sottoespressioni con "or"; "and" non è supportato. Per "all", unire sottoespressioni con "and"; "or" non è supportato. Applicazione di filtri ai campi di tipo Collection(Edm.String) o Collection(Edm.GeographyPoint) Regole per filtrare le raccolte di stringhe

Regole per filtrare le raccolte GeographyPoint
Espressione lambda non valida. Trovato un operatore di confronto (uno fra "lt", "le", "gt" o "ge"). Solo gli operatori di uguaglianza sono consentiti nelle espressioni lambda che eseguono l'iterazione sui campi di tipo Collection(Edm.String). Per "any", usare le espressioni nel formato "x eq y". Per "all", usare le espressioni nei formati "x ne y" o "not (x eq y)". Filtro in un campo di tipo Collection(Edm.String) Regole per filtrare le raccolte di stringhe

Come scrivere filtri di raccolta validi

Le regole per la scrittura di filtri di raccolta validi sono diverse per ogni tipo di dati. Le sezioni seguenti descrivono le regole mostrando esempi di funzionalità di filtro supportate e che non sono:

Regole per filtrare le raccolte di stringhe

All'interno di espressioni lambda per le raccolte di stringhe, gli unici operatori di confronto che possono essere usati sono eq e ne.

Nota

Azure AI Search non supporta gli operatori lt/le/gt/ge per le stringhe, sia all'interno che all'esterno di un'espressione lambda.

Il corpo di un oggetto any può verificare solo l'uguaglianza, mentre il corpo di un oggetto all può verificare solo la disuguaglianza.

È anche possibile combinare più espressioni tramite or nel corpo di un oggetto any e tramite and nel corpo di un oggetto all. Poiché la funzione search.in equivale a combinare i controlli di uguaglianza con or, è consentita anche nel corpo di un oggetto any. Al contrario, not search.in è consentita nel corpo di un oggetto all.

Ad esempio, queste espressioni sono consentite:

  • 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'))

Queste espressioni, invece, non sono consentite:

  • 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'))

Regole per filtrare le raccolte booleane

Il tipo Edm.Boolean supporta solo gli operatori eq e ne. Di conseguenza, non ha molto senso consentire la combinazione di tali clausole che controllano la stessa variabile di intervallo con and/or poiché ciò porterebbe sempre a tautologie o contraddizioni.

Ecco alcuni esempi di filtri per le raccolte booleane consentite:

  • 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 differenza delle raccolte di stringhe, le raccolte booleane non hanno limiti relativi all'operatore che può essere usato e al tipo di espressione lambda. Sia eq che ne possono essere usati nel corpo di any o all.

Le espressioni come le seguenti non sono consentite per le raccolte booleane:

  • 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)

Regole per filtrare le raccolte GeographyPoint

I valori di tipo Edm.GeographyPoint in una raccolta non possono essere confrontati direttamente tra loro. Devono invece essere usati come parametri per le funzioni geo.distance e geo.intersects. La funzione geo.distance a sua volta deve essere confrontata con un valore di distanza usando uno degli operatori di confronto lt, le, gt o ge. Queste regole si applicano anche ai campi Edm.GeographyPoint esterni alla raccolta.

Analogamente alle raccolte di stringhe, le raccolte Edm.GeographyPoint hanno alcune regole sul modo in cui le funzioni geospaziali possono essere usate e combinate nei diversi tipi di espressioni lambda:

  • Gli operatori di confronto che è possibile usare con la funzione geo.distance dipendono dal tipo di espressione lambda. Per any, è possibile usare solo lt o le. Per all, è possibile usare solo gt o ge. È possibile negare le espressioni che coinvolgono geo.distance, ma è necessario modificare l'operatore di confronto (geo.distance(...) lt x diventa not (geo.distance(...) ge x) e geo.distance(...) le x diventa not (geo.distance(...) gt x)).
  • Nel corpo di un oggetto all, la funzione geo.intersects deve essere negata. Viceversa, nel corpo di un oggetto any, la funzione geo.intersects non deve essere negata.
  • Nel corpo di un oggetto any è possibile combinare espressioni geospaziali usando or. Nel corpo di un oggetto all è possibile combinare tali espressioni usando and.

Le limitazioni precedenti esistono per motivi simili alla limitazione di uguaglianza/disuguaglianza nelle raccolte di stringhe. Per un'analisi più approfondita di questi motivi, vedere Informazioni sui filtri di raccolta OData in Azure AI Search.

Ecco alcuni esempi di filtri per le raccolte Edm.GeographyPoint consentite:

  • 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))'))

Le espressioni come le seguenti non sono consentite per le raccolte Edm.GeographyPoint:

  • 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))'))

Regole per filtrare raccolte confrontabili

Questa sezione si applica a tutti i tipi di dati seguenti:

  • Collection(Edm.DateTimeOffset)
  • Collection(Edm.Double)
  • Collection(Edm.Int32)
  • Collection(Edm.Int64)

Tipi come Edm.Int32 e Edm.DateTimeOffset supportano tutti e sei gli operatori di confronto: eq, ne, lt, le, gt e ge. Le espressioni lambda su raccolte di questi tipi possono contenere espressioni semplici usando uno di questi operatori. Questo vale sia per any che per all. Ad esempio, questi filtri sono consentiti:

  • ratings/any(r: r ne 5)
  • dates/any(d: d gt 2017-08-24T00:00:00Z)
  • not margins/all(m: m eq 3.5)

Esistono tuttavia limitazioni sul modo in cui tali espressioni di confronto possono essere combinate in espressioni più complesse all'interno di un'espressione lambda:

  • Regole per any:
    • Le semplici espressioni di disuguaglianza non possono essere combinate in modo utile con altre espressioni. Ad esempio, questa espressione è consentita:

      • ratings/any(r: r ne 5)

      ma questa espressione non lo è:

      • ratings/any(r: r ne 5 and r gt 2)

      e sebbene questa espressione sia consentita, non è utile perché le condizioni si sovrappongono:

      • ratings/any(r: r ne 5 or r gt 7)
    • Le espressioni di confronto semplici che coinvolgono eq, lt, le, gt o ge possono essere combinate con and/or. Ad esempio:

      • ratings/any(r: r gt 2 and r le 5)
      • ratings/any(r: r le 5 or r gt 7)
    • Le espressioni di confronto combinate con and (congiunzioni) possono essere combinate ulteriormente usando or. Questo modulo è noto nella logica booleana come "Forma normale disgiuntiva" (DNF). Ad esempio:

      • ratings/any(r: (r gt 2 and r le 5) or (r gt 7 and r lt 10))
  • Regole per all:
    • Le semplici espressioni di uguaglianza non possono essere combinate in modo utile con altre espressioni. Ad esempio, questa espressione è consentita:

      • ratings/all(r: r eq 5)

      ma questa espressione non lo è:

      • ratings/all(r: r eq 5 or r le 2)

      e sebbene questa espressione sia consentita, non è utile perché le condizioni si sovrappongono:

      • ratings/all(r: r eq 5 and r le 7)
    • Le espressioni di confronto semplici che coinvolgono ne, lt, le, gt o ge possono essere combinate con and/or. Ad esempio:

      • ratings/all(r: r gt 2 and r le 5)
      • ratings/all(r: r le 5 or r gt 7)
    • Le espressioni di confronto combinate con or (disgiunzioni) possono essere combinate ulteriormente usando and. Questo modulo è noto nella logica booleana come "Forma normale congiuntiva" (CNF). Ad esempio:

      • ratings/all(r: (r le 2 or gt 5) and (r lt 7 or r ge 10))

Regole per filtrare raccolte complesse

Le espressioni lambda su raccolte complesse supportano una sintassi molto più flessibile rispetto alle espressioni lambda sulle raccolte di tipi primitivi. È possibile usare qualsiasi costrutto di filtro all'interno di un'espressione lambda che è possibile usare all'esterno di uno, con solo due eccezioni.

Prima di tutto, le funzioni search.ismatch e search.ismatchscoring non sono supportate all'interno di espressioni lambda. Per altre informazioni, vedere Informazioni sui filtri di raccolta OData in Azure AI Search.

In secondo luogo, non è consentito fare riferimento ai campi che non sono associati alla variabile di intervallo (le cosiddette variabili libere). Si considerino ad esempio le due espressioni di filtro OData equivalenti seguenti:

  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))

La prima espressione è consentita, mentre la seconda forma viene rifiutata perché details/margin non è associata alla variabile di intervallo s.

Questa regola si estende anche alle espressioni con variabili associate in un ambito esterno. Tali variabili sono libere rispetto all'ambito in cui appaiono. Ad esempio, la prima espressione è consentita, mentre la seconda espressione equivalente non è consentita perché s/name è libera rispetto all'ambito della variabile di intervallo 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'))

Questa limitazione non dovrebbe rappresentare un problema in ambito pratico, perché è sempre possibile costruire filtri in modo che le espressioni lambda contengano solo variabili associate.

Scheda di riferimento rapido per le regole dei filtri di raccolta

La tabella seguente riepiloga le regole per la creazione di filtri validi per ogni tipo di dati di raccolta.

Tipo di dati Funzionalità consentite nelle espressioni lambda con any Funzionalità consentite nelle espressioni lambda con all
Collection(Edm.ComplexType) Tutto tranne search.ismatch e search.ismatchscoring Uguali
Collection(Edm.String) Confronti con eq o search.in

Combinazione di sottoespressioni con or
Confronti con ne o not search.in()

Combinazione di sottoespressioni con and
Collection(Edm.Boolean) Confronti con eq o ne Uguali
Collection(Edm.GeographyPoint) Uso di geo.distance con lt o le

geo.intersects

Combinazione di sottoespressioni con or
Uso di geo.distance con gt o ge

not geo.intersects(...)

Combinazione di sottoespressioni con and
Collection(Edm.DateTimeOffset), Collection(Edm.Double), Collection(Edm.Int32), Collection(Edm.Int64) Confronti con eq, ne, lt, gt, le o ge

Combinazione di confronti con altre sottoespressioni tramite or

Combinazione di confronti ad eccezione di ne con altre sottoespressioni che usano and

Espressioni che usano combinazioni di and e or in Forma normale disgiuntiva (DNF)
Confronti con eq, ne, lt, gt, le o ge

Combinazione di confronti con altre sottoespressioni tramite and

Combinazione di confronti ad eccezione di eq con altre sottoespressioni che usano or

Espressioni che usano combinazioni di and e or in Forma normale congiuntiva (CNF)

Per esempi di come creare filtri validi per ogni caso, vedere Come scrivere filtri di raccolta validi.

Se si scrivono spesso filtri e la conoscenza delle regole dei primi principi è più utile della loro memorizzazione, vedere Informazioni sui filtri della raccolta OData in Azure AI Search.

Passaggi successivi