Sintaks $filter OData di Azure AI Search

Di Azure AI Search, parameter $filter menentukan kriteria penyertaan atau pengecualian untuk mengembalikan kecocokan dalam hasil pencarian. Artikel ini menguraikan sintaks OData $filter dan memberikan contoh.

Konstruksi dan konstanta jalur bidang dijelaskan dalam gambaran umum bahasa OData di Azure AI Search. Untuk informasi selengkapnya tentang skenario filter, lihat Filter di Pencarian Azure AI.

Sintaks

Filter dalam bahasa OData adalah ungkapan Boolean, yang pada gilirannya dapat berupa salah satu dari beberapa jenis ekspresi, seperti yang ditunjukkan oleh EBNF (Extended Backus-Naur Form berikut):

boolean_expression ::=
    collection_filter_expression
    | logical_expression
    | comparison_expression
    | boolean_literal
    | boolean_function_call
    | '(' boolean_expression ')'
    | variable

/* This can be a range variable in the case of a lambda, or a field path. */
variable ::= identifier | field_path

Diagram sintaksis interaktif juga tersedia:

Catatan

Lihat Referensi sintaks ekspresi OData untuk Pencarian Azure AI untuk EBNF lengkap.

Jenis ekspresi Boolean meliputi:

  • Ekspresi filter koleksi menggunakan any atau all. Ini menerapkan kriteria filter ke bidang koleksi. Untuk informasi selengkapnya, lihat Operator pengumpulan OData di Azure AI Search.
  • Ekspresi logika yang menggabungkan ungkapan Boolean lainnya menggunakan operator and, or, dan not. Untuk informasi selengkapnya, lihat Operator logis OData di Azure AI Search.
  • Ekspresi perbandingan, yang membandingkan variabel bidang atau rentang dengan nilai konstan menggunakan operator eq, ne, gt, lt, ge, dan le. Untuk informasi selengkapnya, lihat Operator perbandingan OData di Azure AI Search. Ekspresi perbandingan juga digunakan untuk membandingkan jarak antara koordinat geo-spasial menggunakan fungsi geo.distance. Untuk informasi selengkapnya, lihat Fungsi geo-spasial OData di Azure AI Search.
  • Literal Boolean true dan false. Konstanta ini terkadang dapat berguna saat membuat filter secara terprogram, tetapi sebaliknya tidak cenderung digunakan dalam praktik.
  • Panggilan ke fungsi Boolean, termasuk:
  • Jalur bidang atau variabel rentang jenis Edm.Boolean. Misalnya, jika indeks Anda memiliki bidang Boolean yang disebut IsEnabled dan Anda ingin menampilkan semua dokumen tempat bidang ini adalah true, ekspresi filter Anda bisa menjadi nama IsEnabled.
  • Ungkapan Boolean dalam tanda kurung. Menggunakan tanda kurung dapat membantu menentukan urutan operasi secara eksplisit dalam filter. Untuk mengetahui informasi selengkapnya tentang prioritas default operator OData, lihat bagian berikutnya.

Prioritas operator dalam filter

Jika Anda menulis ekspresi filter tanpa tanda kurung di sekitar sub-ekspresinya, Azure AI Search akan mengevaluasinya sesuai dengan sekumpulan aturan prioritas operator. Aturan ini didasarkan pada operator mana yang digunakan untuk menggabungkan sub-ekspresi. Tabel berikut ini mencantumkan grup operator secara berurutan dari prioritas tertinggi hingga terendah:

Grupkan Operator
Operator logis not
Operator perbandingan eq, , negt, lt, , ge,le
Operator logis and
Operator logis or

Operator yang lebih tinggi dalam tabel di atas akan "mengikat lebih erat" pada operand-nya daripada operator lain. Misalnya, and lebih diutamakan daripada or, dan operator perbandingan lebih diutamakan daripada yang lain, sehingga dua ekspresi berikut ini setara:

    Rating gt 0 and Rating lt 3 or Rating gt 7 and Rating lt 10
    ((Rating gt 0) and (Rating lt 3)) or ((Rating gt 7) and (Rating lt 10))

Operator not memiliki prioritas tertinggi dari semua -- bahkan lebih tinggi dari operator perbandingan. Itu sebabnya jika Anda mencoba menulis filter seperti ini:

    not Rating gt 5

Anda akan mendapatkan pesan kesalahan ini:

    Invalid expression: A unary operator with an incompatible type was detected. Found operand type 'Edm.Int32' for operator kind 'Not'.

Kesalahan ini terjadi karena operator hanya terkait dengan bidang Rating, yang merupakan jenis Edm.Int32, dan bukan dengan seluruh ekspresi perbandingan. Perbaikannya adalah menempatkan operand not dalam tanda kurung:

    not (Rating gt 5)

Batasan ukuran filter

Ada batasan ukuran dan kompleksitas ekspresi filter yang dapat Anda kirim ke Azure AI Search. Batas didasarkan kira-kira pada jumlah klausul dalam ekspresi filter Anda. Pedoman yang baik adalah bahwa jika Anda memiliki ratusan klausul, Anda berisiko melebihi batas. Sebaiknya rancang aplikasi Anda sedemikian rupa sehingga tidak membuat filter dengan ukuran yang tidak terbatas.

Tip

Menggunakan fungsi search.in alih-alih pemisahan panjang perbandingan kesetaraan dapat membantu menghindari batas klausa filter, karena panggilan fungsi dihitung sebagai klausa tunggal.

Contoh

Temukan semua hotel dengan setidaknya satu kamar dengan tarif dasar kurang dari $200 yang dinilai pada atau di atas 4:

    $filter=Rooms/any(room: room/BaseRate lt 200.0) and Rating ge 4

Temukan semua hotel selain "Sea View Motel" yang telah direnovasi sejak 2010:

    $filter=HotelName ne 'Sea View Motel' and LastRenovationDate ge 2010-01-01T00:00:00Z

Temukan semua hotel yang direnovasi pada tahun 2010 atau yang lebih baru. Literal tanggalwaktu mencakup informasi zona waktu untuk Waktu Standar Pasifik:

    $filter=LastRenovationDate ge 2010-01-01T00:00:00-08:00

Temukan semua hotel yang memiliki tempat parkir dan dengan semua kamar yang bebas rokok:

    $filter=ParkingIncluded and Rooms/all(room: not room/SmokingAllowed)

-ATAU-

    $filter=ParkingIncluded eq true and Rooms/all(room: room/SmokingAllowed eq false)

Temukan semua hotel yang Mewah atau sudah termasuk parkir dan memiliki peringkat 5:

    $filter=(Category eq 'Luxury' or ParkingIncluded eq true) and Rating eq 5

Temukan semua hotel dengan tag "wifi" di setidaknya satu kamar (yang mana setiap kamar memiliki tag yang disimpan di bidang Collection(Edm.String)):

    $filter=Rooms/any(room: room/Tags/any(tag: tag eq 'wifi'))

Temukan semua hotel dengan kamar:

    $filter=Rooms/any()

Temukan semua hotel yang tidak memiliki kamar:

    $filter=not Rooms/any()

Temukan semua hotel dalam jarak 10 kilometer dari titik referensi tertentu (yang mana Location merupakan bidang jenis Edm.GeographyPoint):

    $filter=geo.distance(Location, geography'POINT(-122.131577 47.678581)') le 10

Temukan semua hotel dalam viewport tertentu yang digambarkan sebagai poligon (yang mana Location merupakan bidang jenis Edm.GeographyPoint). Poligon harus ditutup, yang berarti set poin pertama dan terakhir harus sama. Juga, titik harus dicantumkan dalam urutan berlawanan arah jarum jam.

    $filter=geo.intersects(Location, geography'POLYGON((-122.031577 47.578581, -122.031577 47.678581, -122.131577 47.678581, -122.031577 47.578581))')

Temukan semua hotel yang mana bidang "Deskripsi" null. Bidang akan null jika tidak pernah diatur, atau jika secara eksplisit diatur ke null:

    $filter=Description eq null

Temukan semua hotel dengan nama yang sama dengan 'Sea View motel' atau 'Budget hotel'). Frasa ini berisi spasi, dan spasi adalah pemisah default. Anda dapat menentukan pembatas alternatif dalam tanda kutip tunggal sebagai parameter string ketiga:

    $filter=search.in(HotelName, 'Sea View motel,Budget hotel', ',')

Temukan semua hotel dengan nama yang sama dengan 'Sea View motel' atau 'Budget hotel yang dipisahkan dengan '|'):

    $filter=search.in(HotelName, 'Sea View motel|Budget hotel', '|')

Temukan semua hotel yang mana semua kamar memiliki tag 'wifi' atau 'tub':

    $filter=Rooms/any(room: room/Tags/any(tag: search.in(tag, 'wifi, tub')))

Temukan kecocokan pada frasa dalam koleksi, seperti 'heated towel racks' atau 'hairdryer included' dalam tag.

    $filter=Rooms/any(room: room/Tags/any(tag: search.in(tag, 'heated towel racks,hairdryer included', ','))

Temukan dokumen dengan kata "tepi laut". Kueri filter ini identik dengan permintaan pencarian dengan search=waterfront.

    $filter=search.ismatchscoring('waterfront')

Temukan dokumen dengan kata "hostel" dan peringkat lebih besar atau sama dengan 4, atau dokumen dengan kata "motel" dan peringkat sama dengan 5. Permintaan ini tidak dapat diungkapkan tanpa fungsi search.ismatchscoring karena menggabungkan pencarian teks lengkap dengan operasi filter menggunakan or.

    $filter=search.ismatchscoring('hostel') and rating ge 4 or search.ismatchscoring('motel') and rating eq 5

Temukan dokumen tanpa kata "luxury".

    $filter=not search.ismatch('luxury')

Temukan dokumen dengan frasa "ocean view" atau peringkat sama dengan 5. Kueri search.ismatchscoring hanya akan dijalankan pada kolom HotelName dan Description. Dokumen yang hanya cocok dengan klausul kedua pemisah juga akan ditampilkan - hotel dengan Rating yang sama dengan 5. Untuk memperjelas bahwa dokumen tersebut tidak cocok dengan bagian ekspresi yang dinilai, dokumen itu akan ditampilkan dengan skor nol.

    $filter=search.ismatchscoring('"ocean view"', 'Description,HotelName') or Rating eq 5

Temukan hotel dengan istilah "hotel" dan "airport" tidak lebih dari lima kata terpisah dalam deskripsi, dan dengan semua kamar yang bebas rokok. Kueri ini menggunakan bahasa kueri Lucene lengkap.

    $filter=search.ismatch('"hotel airport"~5', 'Description', 'full', 'any') and not Rooms/any(room: room/SmokingAllowed)

Temukan dokumen yang memiliki kata yang dimulai dengan huruf "lux" di bidang Deskripsi. Kueri ini menggunakan pencarian prefiksyang dikombinasikan dengan search.ismatch.

    $filter=search.ismatch('lux*', 'Description')

Langkah berikutnya