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
- Regole per filtrare le raccolte booleane
- Regole per filtrare le raccolte GeographyPoint
- Regole per filtrare raccolte confrontabili
- Regole per filtrare raccolte complesse
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. Perany
, è possibile usare sololt
ole
. Perall
, è possibile usare sologt
oge
. È possibile negare le espressioni che coinvolgonogeo.distance
, ma è necessario modificare l'operatore di confronto (geo.distance(...) lt x
diventanot (geo.distance(...) ge x)
egeo.distance(...) le x
diventanot (geo.distance(...) gt x)
). - Nel corpo di un oggetto
all
, la funzionegeo.intersects
deve essere negata. Viceversa, nel corpo di un oggettoany
, la funzionegeo.intersects
non deve essere negata. - Nel corpo di un oggetto
any
è possibile combinare espressioni geospaziali usandoor
. Nel corpo di un oggettoall
è possibile combinare tali espressioni usandoand
.
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
oge
possono essere combinate conand
/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 usandoor
. 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
oge
possono essere combinate conand
/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 usandoand
. 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:
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))
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
:
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'))
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.