Memahami cara kerja filter koleksi OData di Pencarian Azure AI

Catatan

Pencarian Azure AI tersedia melalui portal Azure, REST API, dan Azure SDK. Ini juga mendukung Foundry IQ, lapisan pengetahuan terkelola yang mengubah konten perusahaan menjadi pangkalan pengetahuan yang dapat digunakan kembali dan sadar izin untuk agen di portal Microsoft Foundry.

Artikel ini menyediakan latar belakang untuk pengembang yang menulis filter tingkat lanjut dengan ekspresi lambda yang kompleks. Artikel ini menjelaskan mengapa aturan untuk filter koleksi ada dengan mengeksplorasi bagaimana Pencarian Azure AI menjalankan filter ini.

Saat Anda membuat filter pada bidang koleksi di Pencarian Azure AI, Anda dapat menggunakan any dan all operator bersama dengan ekspresi lambda. Ekspresi lambda adalah ekspresi Boolean yang merujuk pada variabel rentang. Dalam filter yang menggunakan ekspresi lambda, operator any dan all dianalogikan seperti perulangan for dalam kebanyakan bahasa pemrograman, dengan variabel rentang mengambil peran variabel perulangan, dan ekspresi lambda sebagai isi perulangan. Variabel rentang menggunakan nilai "saat ini" dari kumpulan selama iterasi perulangan.

Setidaknya, seperti itulah cara kerjanya secara konseptual. Sebenarnya, Pencarian Azure AI mengimplementasikan filter dengan cara yang sangat berbeda dibandingkan dengan bagaimana for bekerja dalam perulangan. Idealnya, perbedaan ini tidak terlihat oleh Anda, tetapi dalam situasi tertentu, hal ini tidak berlaku. Hasil akhirnya adalah, ada aturan yang harus Anda ikuti saat menulis ekspresi lambda.

Catatan

Untuk informasi tentang apa aturan untuk filter koleksi, termasuk contoh, lihat Pemecahan masalah filter kumpulan OData di Pencarian Azure AI.

Alasan terbatasnya filter kumpulan

Ada tiga alasan mendasar mengapa fitur filter tidak sepenuhnya didukung untuk semua jenis koleksi:

  1. Hanya operator tertentu yang didukung untuk jenis data tertentu. Misalnya, tidak masuk akal untuk membandingkan nilai true Boolean dan false dengan menggunakan operator perbandingan seperti lt dan gt.
  2. Pencarian Azure AI mendukung filter berkorelasi pada bidang jenis Collection(Edm.ComplexType), tetapi pencarian teks lengkap bidang di atas bidang tersebut tidak terkait.
  3. Pencarian Azure AI menggunakan indeks terbalik untuk menjalankan filter di semua jenis data, termasuk koleksi.

Alasan pertama hanyalah konsekuensi dari bagaimana bahasa OData dan sistem jenis EDM ditentukan. Dua alasan terakhir dijelaskan dengan detail lebih terperinci dalam artikel ini.

Saat Anda menerapkan beberapa kriteria filter atas kumpulan objek kompleks, kriteria berkorelasi karena diterapkan ke setiap objek dalam koleksi. Misalnya, filter berikut mengembalikan hotel yang memiliki setidaknya satu kamar deluxe dengan tarif kurang dari 100:

    Rooms/any(room: room/Type eq 'Deluxe Room' and room/BaseRate lt 100)

Jika pemfilteran tidak berkorelasi, filter di atas mungkin menampilkan hotel yang satu kamarnya bertipe deluxe dan kamar lainnya memiliki tarif dasar kurang dari 100. Filter tersebut tidak masuk akal, karena kedua klausa ekspresi lambda berlaku untuk variabel rentang yang sama, bernama room. Oleh karena itulah filter tersebut berkorelasi.

Namun, untuk pencarian teks lengkap, Anda tidak dapat mereferensikan ke variabel rentang yang spesifik. Jika Anda menggunakan pencarian berbasis bidang untuk mengeluarkan kueri Lucene lengkap seperti berikut:

    Rooms/Type:deluxe AND Rooms/Description:"city view"

Anda mungkin menemukan hotel yang menyediakan satu kamar deluxe, dan kamar lainnya menyebutkan "pemandangan kota" dalam deskripsi. Misalnya, dokumen berikut dengan Id dari 1 akan menyesuaikan kueri:

{
  "value": [
    {
      "Id": "1",
      "Rooms": [
        { "Type": "deluxe", "Description": "Large garden view suite" },
        { "Type": "standard", "Description": "Standard city view room" }
      ]
    },
    {
      "Id": "2",
      "Rooms": [
        { "Type": "deluxe", "Description": "Courtyard motel room" }
      ]
    }
  ]
}

Alasannya adalah Rooms/Type mengacu pada semua istilah yang dianalisis pada bidang Rooms/Type di seluruh dokumen, dan begitu juga dengan Rooms/Description, seperti yang ditampilkan dalam tabel berikut.

Bagaimana Rooms/Type disimpan untuk pencarian teks lengkap:

Istilah dalam Rooms/Type ID Dokumen
mewah 1, 2
standar 1

Bagaimana Rooms/Description disimpan untuk pencarian teks lengkap:

Istilah dalam Rooms/Description ID Dokumen
halaman 2
kota 1
taman 1
besar 1
motel 2
kamar 1, 2
standar 1
suite 1
tampakan 1

Jadi tidak seperti filter di atas, yang dasarnya berisi keterangan "menyesuaikan dokumen jika sebuah kamar memiliki Type yang sama dengan 'Kamar Deluxe' dan kamar yang sama tersebut memiliki BaseRate yang kurang dari 100", kueri pencarian menerangkan "menyesuaikan dokumen jika Rooms/Type memiliki istilah "deluxe" dan Rooms/Description memiliki frasa "panorama kota". Tidak ada konsep ruang individu yang bidangnya dapat dikorelasikan dalam kasus yang terakhir.

Indeks terbalik dan kumpulan

Anda mungkin melihat bahwa ekspresi lambda memiliki batasan yang jauh lebih sedikit daripada koleksi yang kompleks daripada koleksi sederhana, seperti Collection(Edm.Int32) dan Collection(Edm.GeographyPoint). Perbedaan ini ada karena Pencarian Azure AI menyimpan koleksi kompleks sebagai koleksi subdokumen aktual, sementara koleksi sederhana tidak disimpan sebagai koleksi sama sekali.

Misalnya, pertimbangkan bidang kumpulan string yang dapat difilter seperti seasons di indeks untuk retailer online. Beberapa dokumen yang diunggah ke indeks ini mungkin tampak seperti berikut:

{
  "value": [
    {
      "id": "1",
      "name": "Hiking boots",
      "seasons": ["spring", "summer", "fall"]
    },
    {
      "id": "2",
      "name": "Rain jacket",
      "seasons": ["spring", "fall", "winter"]
    },
    {
      "id": "3",
      "name": "Parka",
      "seasons": ["winter"]
    }
  ]
}

Nilai bidang seasons disimpan dalam struktrur yang disebut indeks terbalik, yang terlihat seperti berikut:

Istilah ID Dokumen
musim semi 1, 2
musim panas 1
musim gugur 1, 2
musim dingin 2, 3

Struktur data ini dirancang untuk menjawab satu pertanyaan dengan sangat cepat: Di dokumen mana istilah tertentu muncul? Menjawab pertanyaan ini lebih berfungsi seperti pemeriksaan persamaan biasa dibanding perulangan melalui kumpulan. Bahkan, inilah sebabnya mengapa untuk koleksi string, Pencarian Azure AI hanya memungkinkan eq sebagai operator perbandingan di dalam ekspresi lambda untuk any.

Selanjutnya, kita melihat bagaimana dimungkinkan untuk menggabungkan beberapa pemeriksaan kesetaraan pada variabel rentang yang sama dengan or. Cara ini efektif berkat aljabar dan properti pembilang distributif. Ekspresi ini:

    seasons/any(s: s eq 'winter' or s eq 'fall')

setara dengan:

    seasons/any(s: s eq 'winter') or seasons/any(s: s eq 'fall')

dan setiap dua subekspresi any dapat dijalankan secara efektif menggunakan indeks terbalik. Selain itu, berkat hukum negasi pembilang, ekspresi ini:

    seasons/all(s: s ne 'winter' and s ne 'fall')

setara dengan:

    not seasons/any(s: s eq 'winter' or s eq 'fall')

yang menjadi alasan kita dapat menggunakan all dengan ne dan and.

Catatan

Meskipun detail tersebut ada di luar cakupan dokumen ini, prinsip yang sama juga dapat diterapkan pada jarak dan pengujian irisan untuk kumpulan titik geo-spasial. Inilah alasan mengapa, dalam any:

  • geo.intersects tidak dapat dinegasikan
  • geo.distance harus dibandingkan menggunakan lt atau le
  • Ekspresi harus digabungkan dengan or, bukan and

Aturan sebaliknya berlaku untuk all.

Variasi ekspresi jenis data yang lebih beragam diizinkan saat memfilter kumpulan jenis data yang mendukung operator lt, gt, le, dan ge, misalnya ambil Collection(Edm.Int32) sebagai contoh. Secara khusus, Anda dapat menggunakan and sebagaimana or di any, asalkan ekspresi perbandingan yang mendasarinya digabungkan ke perbandingan rentang menggunakan and, yang kemudian digabungkan lebih lanjut menggunakan or. Struktur ungkapan Boolean disebut dengan Disjunctive Normal Form (DNF), atau yang dikenal dengan "OR of AND". Sebaliknya, ekspresi lambda untuk all pada jenis data ini diharuskan berada dalam Conjunctive Normal Form (CNF), atau dikenal dengan "dan dari atau". Pencarian Azure AI memungkinkan perbandingan rentang tersebut karena dapat menjalankannya menggunakan indeks terbalik secara efisien, sama seperti dapat melakukan pencarian jangka cepat untuk string.

Kesimpulannya, berikut aturan praktis terkait hal-hal yang diizinkan dalam ekspresi lambda:

  • Dalam any, pemeriksaan positif selalu diizinkan, seperti pemeriksaan kesetaraan, perbandingan rentang, geo.intersects, atau geo.distance dibandingkan dengan lt atau le (anggap saja "kedekatan" sebagai kesetaraan ketika memeriksa jarak).
  • Dalam any, or selalu diizinkan. Anda hanya dapat menggunakan and untuk data yang mengungkapkan pemeriksaan rentang, dan hanya jika Anda menggunakan OR of AND (DNF).
  • Di dalam all, aturan dibalikkan. Hanya cek negatif yang diizinkan, Anda dapat menggunakan and selalu, dan Anda hanya dapat menggunakan or untuk pemeriksaan rentang yang dinyatakan sebagai AND dari OR (CNF).

Dalam praktiknya, ini adalah jenis filter yang sebagian besar akan Anda gunakan. Meskipun demikian, memahami batasan kemungkinan tetaplah bermanfaat.

Untuk mengetahui contoh filter apa saja yang diizinkan atau yang tidak diizinkan, lihat Cara menulis filter kumpulan yang valid.

Langkah berikutnya