Pemecahan masalah filter koleksi OData di Azure AI Search
Untuk memfilter bidang koleksi di Azure AI Search, Anda dapat menggunakan any
operator dan all
bersama dengan ekspresi lambda. Ekspresi lambda adalah subfilter yang diterapkan ke setiap elemen koleksi.
Tidak setiap fitur ekspresi filter tersedia di dalam isi ekspresi lambda. Fitur yang tersedia berbeda bergantung pada jenis data bidang pengumpulan yang ingin Anda filter. Ini dapat mengakibatkan kesalahan jika Anda mencoba menggunakan fitur dalam ekspresi lambda yang tidak didukung dalam konteks tersebut. Jika Anda mengalami kesalahan seperti itu saat mencoba menulis filter kompleks di atas bidang pengumpulan, artikel ini akan membantu Anda memecahkan masalah.
Kesalahan filter pengumpulan umum
Tabel berikut ini mencantumkan kesalahan yang mungkin Anda temui saat mencoba menjalankan filter koleksi. Kesalahan ini terjadi saat Anda menggunakan fitur ekspresi filter yang tidak didukung di dalam ekspresi lambda. Setiap kesalahan memberikan beberapa panduan tentang cara Anda dapat menulis ulang filter untuk menghindari kesalahan. Tabel ini juga menyertakan tautan ke bagian yang relevan dari artikel ini yang menyediakan informasi selengkapnya tentang cara menghindari kesalahan tersebut.
Pesan kesalahan | Situasi | Detail |
---|---|---|
Fungsi ismatch ini tidak memiliki parameter yang terikat ke variabel rentang 's'. Hanya referensi bidang terikat yang didukung di dalam ekspresi lambda ('any' atau 'all'). Namun, Anda dapat mengubah filter sehingga ismatch fungsi berada di luar ekspresi lambda dan mencoba lagi. |
Menggunakan search.ismatch atau search.ismatchscoring di dalam ekspresi lambda |
Aturan untuk memfilter kumpulan kompleks |
Ekspresi lambda tidak valid. Menemukan pengujian untuk kesetaraan atau ketidaksetaraan di mana sebaliknya diharapkan dalam ekspresi lambda yang berulang di atas bidang koleksi tipe(Edm.String). Untuk 'any', gunakan ekspresi formulir 'x eq y' atau 'search.in(...)'. Untuk 'semua', gunakan ekspresi formulir 'x ne y', 'not (x eq y)', atau 'not search.in(...)'. | Pemfilteran pada bidang jenis Collection(Edm.String) |
Aturan untuk memfilter koleksi string |
Ekspresi lambda tidak valid. Menemukan bentuk ekspresi Boolean kompleks yang tidak didukung. Untuk 'any', gunakan ekspresi yang merupakan 'OU AND', juga dikenal sebagai Bentuk Normal Disjunctive. Misalnya: (a and b) or (c and d) di mana a, b, c, dan d adalah subekspresi perbandingan atau kesetaraan. Untuk 'semua', gunakan ekspresi yang merupakan 'ID OU', juga dikenal sebagai Bentuk Normal Konjugtif. Misalnya: (a or b) and (c or d) di mana a, b, c, dan d adalah subekspresi perbandingan atau ketidaksamaan. Contoh ekspresi perbandingan: 'x gt 5', 'x le 2'. Contoh ekspresi kesetaraan: 'x eq 5'. Contoh ekspresi ketidaksetaraan: 'x ne 5'. |
Pemiflteran pada bidang jenis Collection(Edm.DateTimeOffset) , Collection(Edm.Double) , Collection(Edm.Int32) , atau Collection(Edm.Int64) |
Aturan untuk memfilter kumpulan yang sebanding |
Ekspresi lambda tidak valid. Menemukan penggunaan geo.distance() atau geo.intersects() yang tidak didukung dalam ekspresi lambda yang berulang di atas bidang jenis Koleksi(Edm.GeographyPoint). Untuk 'any', pastikan Anda membandingkan geo.distance() menggunakan operator 'lt' atau 'le' dan pastikan bahwa penggunaan geo.intersects() tidak dinegasikan. Untuk 'all', pastikan Anda membandingkan geo.distance() menggunakan operator 'gt' atau 'ge' dan pastikan bahwa setiap penggunaan geo.intersects() ditiadakan. | Pemfilteran pada bidang jenis Collection(Edm.GeographyPoint) |
Aturan untuk memfilter kumpulan GeographyPoint |
Ekspresi lambda tidak valid. Ekspresi Boolean kompleks tidak didukung dalam ekspresi lambda yang mengulangi bidang jenis Koleksi(Edm.GeographyPoint). Untuk 'any', gabungkan subekspresi dengan 'or'; 'and' tidak didukung. Untuk 'semua', gabungkan subekspresi dengan 'dan'; 'or' tidak didukung. | Pemfilteran pada bidang jenis Collection(Edm.String) atau Collection(Edm.GeographyPoint) |
Aturan untuk memfilter koleksi string Aturan untuk memfilter kumpulan GeographyPoint |
Ekspresi lambda tidak valid. Menemukan operator perbandingan (salah satu dari 'lt', 'le', 'gt', atau 'ge'). Hanya operator kesetaraan yang diperbolehkan dalam ekspresi lambda yang berulang di atas bidang jenis Collection(Edm.String). Untuk 'any', ekspresi se dari formulir 'x eq y'. Untuk 'all', gunakan ekspresi formulir 'x ne y' atau 'not (x eq y)'. | Pemfilteran pada bidang jenis Collection(Edm.String) |
Aturan untuk memfilter koleksi string |
Cara menulis filter koleksi yang valid
Aturan untuk menulis filter pengumpulan yang valid berbeda untuk setiap jenis data. Bagian berikut menguraikan aturan dengan memperlihatkan contoh fitur filter yang didukung dan yang tidak didukung:
- Aturan untuk memfilter koleksi string
- Aturan untuk memfilter kumpulan Boolean
- Aturan untuk memfilter kumpulan GeographyPoint
- Aturan untuk memfilter kumpulan yang sebanding
- Aturan untuk memfilter kumpulan kompleks
Aturan untuk memfilter koleksi string
Di dalam ekspresi lambda untuk kumpulan string, satu-satunya operator perbandingan yang dapat digunakan adalah eq
dan ne
.
Catatan
Azure AI Search tidak mendukung lt
gt
ge
/le
//operator untuk string, baik di dalam atau di luar ekspresi lambda.
Tubuh seseorang any
hanya dapat menguji kesetaraan sementara tubuh seseorang all
hanya dapat menguji ketidaksetaraan.
Dimungkinkan juga untuk menggabungkan beberapa ekspresi melalui or
dalam tubuh any
, dan melalui and
dalam tubuh dari all
. Karena fungsi search.in
setara dengan menggabungkan pemeriksaan kesetaraan dengan or
, itu juga diperbolehkan dalam tubuh any
. Sebaliknya, not search.in
diperbolehkan dalam tubuh all
.
Misalnya, ekspresi ini diperbolehkan:
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'))
Meskipun ekspresi ini tidak diizinkan:
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'))
Aturan untuk memfilter kumpulan Boolean
Jenis Edm.Boolean
ini hanya mendukung operator eq
dan ne
. Dengan demikian, tidak masuk akal untuk memungkinkan menggabungkan klausa seperti itu yang memeriksa variabel rentang yang sama dengan and
/ or
karena itu akan selalu mengarah pada tautologi atau kontradiksi.
Berikut adalah beberapa contoh filter pada kumpulan Boolean yang diizinkan:
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))
Tidak seperti kumpulan string, kumpulan Boolean tidak memiliki batasan pada operator yang dapat digunakan dalam jenis ekspresi lambda. Baikeq
maupun ne
dapat digunakan dalam tubuh any
atau all
.
Ekspresi seperti berikut tidak diperbolehkan untuk kumpulan Boolean:
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)
Aturan untuk memfilter kumpulan GeographyPoint
Nilai jenis Edm.GeographyPoint
dalam kumpulan tidak dapat dibandingkan secara langsung satu sama lain. Sebaliknya, itu harus digunakan sebagai parameter untuk fungsi geo.distance
dan geo.intersects
. Fungsi geo.distance
pada gilirannya harus dibandingkan dengan nilai jarak menggunakan salah satu operator perbandingan lt
,le
, gt
, atau ge
. Aturan ini juga berlaku untuk bidang Edm.GeographyPoint nonkoleksi.
Seperti kumpulan string, kumpulan Edm.GeographyPoint
memiliki beberapa aturan tentang cara fungsi geo-spasial dapat digunakan dan dikombinasikan dalam berbagai jenis ekspresi lambda:
- Operator perbandingan yang dapat Anda gunakan dengan fungsi
geo.distance
bergantung pada jenis ekspresi lambda. Untukany
, Anda hanya dapat menggunakanlt
ataule
. Untukall
, Anda hanya dapat menggunakangt
atauge
. Anda dapat meniadakan ekspresi yang melibatkangeo.distance
, tetapi Anda harus mengubah operator perbandingan (geo.distance(...) lt x
menjadinot (geo.distance(...) ge x)
dangeo.distance(...) le x
menjadinot (geo.distance(...) gt x)
). - Dalam tubuh
all
, fungsigeo.intersects
harus dinegasikan. Sebaliknya, dalam tubuhany
, fungsigeo.intersects
tidak boleh dinegasikan. - Dalam tubuh ekspresi
any
geo-spasial dapat dikombinasikan menggunakanor
. Dalam tubuh ekspresiall
geo-spasial dapat dikombinasikan menggunakanand
.
Batasan di atas ada karena alasan yang sama seperti batasan kesetaraan/ketidaksetaraan pada kumpulan string. Lihat Memahami filter koleksi OData di Azure AI Search untuk melihat lebih dalam alasan ini.
Berikut adalah beberapa contoh filter pada kumpulan Edm.GeographyPoint
yang diizinkan:
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))'))
Ekspresi seperti berikut ini tidak diizinkan untuk Edm.GeographyPoint
koleksi:
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))'))
Aturan untuk memfilter kumpulan yang sebanding
Bagian ini berlaku untuk semua jenis data berikut:
Collection(Edm.DateTimeOffset)
Collection(Edm.Double)
Collection(Edm.Int32)
Collection(Edm.Int64)
Jenis seperti Edm.Int32
dan Edm.DateTimeOffset
mendukung keenam operator perbandingan: eq
, ne
, lt
, le
, gt
, dan ge
. Ekspresi Lambda atas kumpulan jenis ini dapat berisi ekspresi sederhana menggunakan salah satu operator ini. Ini berlaku untuk any
dan all
. Misalnya, filter ini diperbolehkan:
ratings/any(r: r ne 5)
dates/any(d: d gt 2017-08-24T00:00:00Z)
not margins/all(m: m eq 3.5)
Namun, ada batasan tentang cara ekspresi perbandingan tersebut dapat digabungkan menjadi ekspresi yang lebih kompleks di dalam ekspresi lambda:
- Aturan untuk
any
:Ekspresi ketidaksetaraan sederhana tidak dapat digabungkan secara berguna dengan ekspresi lainnya. Misalnya, ekspresi ini diperbolehkan:
ratings/any(r: r ne 5)
tapi ekspresi ini tidak diperbolehkan:
ratings/any(r: r ne 5 and r gt 2)
dan sementara ekspresi ini diperbolehkan, ekspresi ini tidak berguna karena kondisi tumpang tindih:
ratings/any(r: r ne 5 or r gt 7)
Ekspresi perbandingan sederhana yang melibatkan
eq
,lt
,le
,gt
, atauge
dapat dikombinasikan denganand
/or
. Contohnya:ratings/any(r: r gt 2 and r le 5)
ratings/any(r: r le 5 or r gt 7)
Ekspresi perbandingan yang dikombinasikan dengan
and
(konjungsi) dapat digabungkan lebih lanjut menggunakanor
. Bentuk ini dikenal dalam logika Boolean sebagai "Formulir Normal Disjunctive" (DNF). Contohnya:ratings/any(r: (r gt 2 and r le 5) or (r gt 7 and r lt 10))
- Aturan untuk
all
:Ekspresi ketidaksetaraan sederhana tidak dapat digabungkan secara berguna dengan ekspresi lainnya. Misalnya, ekspresi ini diperbolehkan:
ratings/all(r: r eq 5)
tapi ekspresi ini tidak diperbolehkan:
ratings/all(r: r eq 5 or r le 2)
dan sementara ekspresi ini diperbolehkan, ekspresi ini tidak berguna karena kondisi tumpang tindih:
ratings/all(r: r eq 5 and r le 7)
Ekspresi perbandingan sederhana yang melibatkan
ne
,lt
,le
,gt
, atauge
dapat dikombinasikan denganand
/or
. Contohnya:ratings/all(r: r gt 2 and r le 5)
ratings/all(r: r le 5 or r gt 7)
Ekspresi perbandingan yang dikombinasikan dengan
or
(disjungsi) dapat digabungkan lebih lanjut menggunakanand
. Bentuk ini dikenal dalam logika Boolean sebagai "Formulir Normal Conjunctive" (CNF). Contohnya:ratings/all(r: (r le 2 or gt 5) and (r lt 7 or r ge 10))
Aturan untuk memfilter kumpulan kompleks
Ekspresi Lambda atas kumpulan kompleks mendukung sintaks yang jauh lebih fleksibel daripada ekspresi lambda atas kumpulan jenis primitif. Anda dapat menggunakan filter yang dibangun di dalam ekspresi lambda seperti itu yang dapat Anda gunakan di luar satu, hanya dengan dua pengecualian.
Pertama, fungsi search.ismatch
dan search.ismatchscoring
tidak didukung di dalam ekspresi lambda. Untuk informasi selengkapnya, lihat Memahami filter koleksi OData di Azure AI Search.
Kedua, bidang referensi yang tidak terikat ke variabel rentang (yang disebut variabel bebas) tidak diperbolehkan. Misalnya, pertimbangkan dua ekspresi filter OData yang setara berikut:
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))
Ekspresi pertama diizinkan, sementara formulir kedua ditolak karena details/margin
tidak terikat ke variabel s
rentang .
Aturan ini juga meluas ke ekspresi yang memiliki variabel yang terikat dalam lingkup luar. Variabel semacam itu bebas sehubungan dengan ruang lingkup tempat mereka muncul. Misalnya, ekspresi pertama diperbolehkan, sedangkan ekspresi setara kedua tidak diperbolehkan karena s/name
bebas sehubungan dengan lingkup variabel rentang 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'))
Batasan ini seharusnya tidak menjadi masalah dalam praktik karena selalu mungkin untuk membangun filter sedemikian rupa sehingga ekspresi lambda hanya mengandung variabel terikat.
Lembar contekan untuk aturan filter kumpulan
Tabel berikut meringkas aturan untuk membuat filter yang valid untuk setiap jenis data pengumpulan.
Jenis Data | Fitur yang diizinkan dalam ekspresi lambda dengan any |
Fitur yang diizinkan dalam ekspresi lambda dengan all |
---|---|---|
Collection(Edm.ComplexType) |
Semuanya kecuali search.ismatch dan search.ismatchscoring |
Sama |
Collection(Edm.String) |
Perbandingan dengan eq atau search.in Menggabungkan sub-ekspresi dengan or |
Perbandingan dengan ne atau not search.in() Menggabungkan sub-ekspresi dengan and |
Collection(Edm.Boolean) |
Perbandingan dengan eq atau ne |
Sama |
Collection(Edm.GeographyPoint) |
Menggunakan geo.distance dengan lt atau le geo.intersects Menggabungkan sub-ekspresi dengan or |
Menggunakan geo.distance dengan gt atau ge not geo.intersects(...) Menggabungkan sub-ekspresi dengan and |
Collection(Edm.DateTimeOffset) , , Collection(Edm.Double) Collection(Edm.Int32) ,Collection(Edm.Int64) |
Perbandingan menggunakan eq , ne , lt , gt , le , atau ge Menggabungkan perbandingan dengan sub-ekspresi lain menggunakan or Menggabungkan perbandingan kecuali ne dengan sub-ekspresi lain menggunakan and Ekspresi menggunakan kombinasi and dan or dalam Bentuk Normal Disjungtif (DNF) |
Perbandingan menggunakan eq , ne , lt , gt , le , atau ge Menggabungkan perbandingan dengan sub-ekspresi lain menggunakan and Menggabungkan perbandingan kecuali eq dengan sub-ekspresi lain menggunakan or Ekspresi yang menggunakan kombinasi and dan or dalam Bentuk Normal Konjungtif (CNF) |
Untuk contoh cara membuat filter yang valid untuk setiap kasus, lihat Cara menulis filter kumpulan yang valid.
Jika Anda sering menulis filter, dan memahami aturan dari prinsip pertama akan membantu Anda lebih dari sekadar menghafalnya, lihat Memahami filter koleksi OData di Azure AI Search.