Baca dalam bahasa Inggris

Bagikan melalui


Menambahkan navigasi tersaring ke aplikasi pencarian

Navigasi tersaring digunakan untuk pemfilteran drilldown yang diarahkan sendiri pada hasil kueri di aplikasi pencarian, di mana aplikasi Anda menawarkan kontrol formulir untuk pencakupan pencarian ke grup dokumen (misalnya, kategori atau merek), dan Azure AI Search menyediakan struktur dan filter data untuk mendukung pengalaman.

Dalam artikel ini, pelajari langkah-langkah dasar untuk membuat struktur navigasi tersaring di Azure AI Search.

  • Mengatur atribut bidang dalam indeks
  • Membuat struktur permintaan dan respons
  • Menambahkan kontrol navigasi dan filter di lapisan presentasi

Kode di lapisan presentasi melakukan angkat berat dalam pengalaman navigasi tersaring. Demo dan sampel yang tercantum di akhir artikel ini menyediakan kode kerja yang menunjukkan kepada Anda cara menyatukan semuanya.

Navigasi tersaring di halaman pencarian

Faset bersifat dinamis dan ditampilkan pada kueri. Respons pencarian membawa serta semua kategori faset yang digunakan untuk menavigasi dokumen dalam hasilnya. Kueri dijalankan terlebih dahulu, dan kemudian faset ditarik dari hasil saat ini dan dirakit menjadi struktur navigasi tersaring.

Di Azure AI Search, faset adalah satu lapisan dalam dan tidak bisa hierarkis. Jika Anda tidak terbiasa dengan struktur navigasi tersaring, contoh berikut menunjukkannya di sebelah kiri. Hitungan menunjukkan jumlah kecocokan untuk setiap faset. Dokumen yang sama dapat diwakili dalam berbagai faset.

Cuplikan layar hasil pencarian tersaring.

Faset dapat membantu Anda menemukan apa yang Anda cari, sambil memastikan bahwa Anda tidak mendapatkan hasil nol. Sebagai pengembang, faset memungkinkan Anda mengekspos kriteria pencarian yang paling berguna untuk menavigasi indeks pencarian Anda.

Mengaktifkan faset dalam indeks

Faceting diaktifkan berdasarkan bidang demi bidang dalam definisi indeks ketika Anda mengatur atribut "dapat dibuat faset" menjadi true.

Meskipun tidak sepenuhnya diperlukan, Anda juga harus mengatur atribut "dapat disaring" sehingga Anda dapat membangun filter yang diperlukan yang mendukung pengalaman navigasi tersaring dalam aplikasi pencarian Anda.

Contoh berikut dari indeks sampel "hotel" menunjukkan "dapat dibuat faset" dan "dapat difilter" pada bidang kardinalitas rendah yang berisi nilai tunggal atau frasa pendek: "Kategori", "Tag", "Rating".

{
  "name": "hotels",  
  "fields": [
    { "name": "hotelId", "type": "Edm.String", "key": true, "searchable": false, "sortable": false, "facetable": false },
    { "name": "Description", "type": "Edm.String", "filterable": false, "sortable": false, "facetable": false },
    { "name": "HotelName", "type": "Edm.String", "facetable": false },
    { "name": "Category", "type": "Edm.String", "filterable": true, "facetable": true },
    { "name": "Tags", "type": "Collection(Edm.String)", "filterable": true, "facetable": true },
    { "name": "Rating", "type": "Edm.Int32", "filterable": true, "facetable": true },
    { "name": "Location", "type": "Edm.GeographyPoint" }
  ]
}

Memilih bidang

Faset dapat dihitung melalui bidang dan koleksi nilai tunggal. Bidang yang paling sesuai dalam navigasi tersaring memiliki karakteristik ini:

  • Kardinalitas rendah (sejumlah kecil nilai berbeda yang berulang di seluruh dokumen di korpus pencarian Anda)

  • Nilai deskriptif pendek (satu atau dua kata) yang dirender dengan baik di pohon navigasi

Nilai dalam bidang, dan bukan nama bidang itu sendiri, menghasilkan faset dalam struktur navigasi tersaring. Jika faset adalah bidang string bernama Warna, faset berwarna biru, hijau, dan nilai lainnya untuk bidang tersebut.

Sebagai praktik terbaik, periksa bidang untuk nilai null, kesalahan ejaan atau perbedaan kasus, dan versi tunggal dan jamak dari kata yang sama. Secara default, filter dan faset tidak menjalani analisis leksikal atau pemeriksaan ejaan, yang berarti bahwa semua nilai bidang "faset" adalah faset potensial, bahkan jika kata-kata berbeda dengan satu karakter. Secara opsional, Anda dapat menetapkan normalizer ke bidang "dapat difilter" dan "dapat difaset" untuk memuluskan variasi dalam casing dan karakter.

Default di REST dan Azure SDK

Jika Anda menggunakan salah satu Azure SDK, kode Anda harus secara eksplisit mengatur atribut bidang. Sebaliknya, REST API memiliki default untuk atribut bidang berdasarkan jenis data. Jenis data berikut adalah "dapat disaring" dan "dapat dibuat faset" secara default:

  • Edm.String
  • Edm.DateTimeOffset
  • Edm.Boolean
  • Edm.Int32, , Edm.Int64Edm.Double
  • Kumpulan jenis di atas, misalnya, Collection(Edm.String) atau Collection(Edm.Double)

Anda tidak dapat menggunakan Edm.GeographyPoint bidang atau Collection(Edm.GeographyPoint) dalam navigasi tersaring. Faset paling efektif untuk bidang dengan kardinalitas rendah. Karena resolusi koordinat geografis, jarang ada dua set koordinat yang sama dalam himpunan data tertentu. Dengan demikian, faset tidak didukung untuk koordinat geografis. Anda memerlukan bidang kota atau wilayah untuk faset berdasarkan lokasi.

Tip

Sebagai praktik terbaik untuk pengoptimalan kinerja dan penyimpanan, nonaktifkan faset untuk bidang yang tidak boleh digunakan sebagai faset. Khususnya, bidang string untuk nilai unik, seperti ID atau nama produk, harus diatur ke "facetable": false untuk mencegah penggunaan yang tidak disengaja (dan tidak efektif) dalam navigasi tersaring. Hal ini terutama berlaku untuk REST API yang memungkinkan filter dan faset secara default.

Permintaan dan respons faset

Faset ditentukan pada kueri, dan struktur navigasi tersaring dikembalikan di bagian atas respons. Struktur permintaan dan tanggapan cukup sederhana. Bahkan, pekerjaan nyata di balik navigasi tersaring terletak di lapisan presentasi, tercakup dalam bagian selanjutnya.

Contoh REST berikut adalah kueri yang tidak memenuhi syarat ("search": "*") yang masuk cakupan ke seluruh indeks (lihat sampel hotel bawaan). Faset biasanya merupakan daftar bidang, tetapi kueri ini hanya memperlihatkan satu untuk respons yang lebih mudah dibaca.

POST https://{{service_name}}.search.windows.net/indexes/hotels/docs/search?api-version={{api_version}}
{
    "search": "*",
    "queryType": "simple",
    "select": "",
    "searchFields": "",
    "filter": "",
    "facets": [ "Category"], 
    "orderby": "",
    "count": true
}

Sangat berguna untuk menginisialisasi halaman pencarian dengan kueri terbuka untuk sepenuhnya mengisi struktur navigasi tersaring. Segera setelah Anda meneruskan istilah kueri dalam permintaan, struktur navigasi tersaring dilingkupkan hanya untuk kecocokan dalam hasil, bukan seluruh indeks.

Respons untuk contoh mencakup struktur navigasi tersaring di bagian atas. Struktur terdiri dari nilai "Kategori" dan hitungan hotel untuk masing-masing. Hal ini diikuti oleh sisa hasil pencarian, dipangkas di sini untuk singkatnya. Contoh ini bekerja dengan baik karena beberapa alasan. Jumlah faset untuk bidang ini berada di bawah batas (defaultnya adalah 10) sehingga semuanya muncul, dan setiap hotel dalam indeks 50 hotel diwakili dalam salah satu kategori ini.

{
    "@odata.context": "https://demo-search-svc.search.windows.net/indexes('hotels')/$metadata#docs(*)",
    "@odata.count": 50,
    "@search.facets": {
        "Category": [
            {
                "count": 13,
                "value": "Budget"
            },
            {
                "count": 12,
                "value": "Resort and Spa"
            },
            {
                "count": 9,
                "value": "Luxury"
            },
            {
                "count": 7,
                "value": "Boutique"
            },
            {
                "count": 5,
                "value": "Suite"
            },
            {
                "count": 4,
                "value": "Extended-Stay"
            }
        ]
    },
    "value": [
        {
            "@search.score": 1.0,
            "HotelId": "1",
            "HotelName": "Stay-Kay City Hotel",
            "Description": "The hotel is ideally located on the main commercial artery of the city in the heart of New York. A few minutes away is Time's Square and the historic centre of the city, as well as other places of interest that make New York one of America's most attractive and cosmopolitan cities.",
            "Category": "Boutique",
            "Tags": [
                "pool",
                "air conditioning",
                "concierge"
            ],
            "ParkingIncluded": false,
        }
    ]
}

Sintaks faset

Parameter kueri faset diatur ke daftar bidang "dapat dibuat faset" yang dibatasi koma dan tergantung pada jenis data, dapat di parameter lebih lanjut untuk mengatur jumlah, mensortir urutan, dan rentang: count:<integer>, sort:<>, interval:<integer>, and values:<list>. Untuk detail selengkapnya tentang parameter faset, lihat parameter kueri di REST API.

POST https://{{service_name}}.search.windows.net/indexes/hotels/docs/search?api-version={{api_version}}
{
    "search": "*",
    "facets": [ "Category", "Tags,count:5", "Rating,values:1|2|3|4|5"],
    "count": true
}

Untuk setiap pohon navigasi tersaring, ada batas default dari sepuluh faset teratas. Default ini masuk akal untuk struktur navigasi karena default ini menjaga agar daftar nilai tetap berada dalam ukuran yang dapat dikelola. Anda dapat mengganti default dengan menetapkan nilai yang akan "dihitung". Misalnya, "Tags,count:5" mengurangi jumlah tag di bawah bagian Tag ke lima besar.

Hanya untuk nilai Numerik dan DateTime, Anda dapat secara eksplisit mengatur nilai pada bidang faset (misalnya, facet=Rating,values:1|2|3|4|5) untuk memisahkan hasil menjadi rentang bersebelahan (baik rentang berdasarkan nilai numerik atau periode waktu). Atau, Anda dapat menambahkan "interval", seperti dalam facet=Rating,interval:1.

Setiap rentang dibangun menggunakan 0 sebagai titik awal, nilai dari daftar sebagai titik akhir, lalu dipangkas dari rentang sebelumnya untuk membuat interval diskrit.

Perbedaan dalam jumlah faset

Dalam keadaan tertentu, Anda mungkin menemukan bahwa jumlah faset tidak sepenuhnya akurat karena arsitektur sharding. Setiap indeks pencarian tersebar di beberapa pecahan, dan setiap shard melaporkan aspek N teratas menurut jumlah dokumen, yang kemudian digabungkan menjadi satu hasil. Karena ini hanya faset N teratas untuk setiap shard, anda dapat melewatkan atau menghitung dokumen yang cocok dalam respons faset.

Untuk menjamin akurasi, Anda dapat secara artifisial menggelembungkan hitungan:<angka> ke angka besar untuk memaksa pelaporan penuh dari setiap pecahan. Anda dapat menentukan "count": "0" faset tanpa batas. Atau, Anda dapat mengatur "hitungan" ke nilai yang lebih besar dari atau sama dengan jumlah nilai unik bidang tersaring. Misalnya, jika Anda menghadapi bidang "ukuran" yang memiliki lima nilai unik, Anda dapat mengatur "count:5" untuk memastikan semua kecocokan diwakili dalam respons faset.

Tradeoff dengan solusi ini adalah peningkatan latensi kueri, jadi gunakan hanya jika perlu.

Lapisan presentasi

Dalam kode aplikasi, polanya adalah menggunakan parameter kueri faset untuk mengembalikan struktur navigasi tersaring bersama dengan hasil faset, ditambah $filter ekspresi. Ekspresi filter menangani peristiwa klik dan semakin mempersempit hasil pencarian berdasarkan pemilihan faset.

Kombinasi faset dan filter

Cuplikan kode berikut dari JobsSearch.cs file dalam demo NYCJobs menambahkan Judul Bisnis yang dipilih ke filter jika Anda memilih nilai dari faset Judul Bisnis.

if (businessTitleFacet != "")
  filter = "business_title eq '" + businessTitleFacet + "'";

Berikut adalah contoh lain dari sampel hotel. Cuplikan kode berikut ditambahkan categoryFacet ke filter jika pengguna memilih nilai dari faset kategori.

if (!String.IsNullOrEmpty(categoryFacet))
    filter = $"category eq '{categoryFacet}'";

HTML untuk navigasi tersaring

Contoh berikut, diambil dari file index.cshtml aplikasi contoh NYCJobs, menunjukkan struktur HTML statik untuk menampilkan navigasi tersaring pada halaman hasil pencarian. Daftar faset dibangun atau dibangun kembali secara dinamis saat Anda mengirimkan istilah pencarian, atau memilih atau menghapus faset.

<div class="widget sidebar-widget jobs-filter-widget">
  <h5 class="widget-title">Filter Results</h5>
    <p id="filterReset"></p>
    <div class="widget-content">

      <h6 id="businessTitleFacetTitle">Business Title</h6>
      <ul class="filter-list" id="business_title_facets">
      </ul>

      <h6>Location</h6>
      <ul class="filter-list" id="posting_type_facets">
      </ul>

      <h6>Posting Type</h6>
      <ul class="filter-list" id="posting_type_facets"></ul>

      <h6>Minimum Salary</h6>
      <ul class="filter-list" id="salary_range_facets">
      </ul>

  </div>
</div>

Membangun HTML secara dinamis

Cuplikan kode berikut dari index.cshtml (juga dari demo NYCJobs) secara dinamis membangun HTML untuk menampilkan faset pertama, Judul Bisnis. Fungsi serupa secara dinamis membangun HTML untuk faset lainnya. Setiap faset memiliki label dan hitungan, yang menampilkan jumlah item yang ditemukan untuk hasil faset tersebut.

function UpdateBusinessTitleFacets(data) {
  var facetResultsHTML = '';
  for (var i = 0; i < data.length; i++) {
    facetResultsHTML += '<li><a href="javascript:void(0)" onclick="ChooseBusinessTitleFacet(\'' + data[i].Value + '\');">' + data[i].Value + ' (' + data[i].Count + ')</span></a></li>';
  }

  $("#business_title_facets").html(facetResultsHTML);
}

Tips untuk bekerja dengan faset

Bagian ini adalah kumpulan tips dan solusi yang mungkin bermanfaat.

Mempertahankan struktur navigasi aspek secara asinkron dari hasil yang difilter

Salah satu tantangan navigasi tersaring di Azure AI Search adalah bahwa faset hanya ada untuk hasil saat ini. Dalam praktiknya, umum untuk mempertahankan sekumpulan faset statik sehingga pengguna dapat menavigasi secara terbalik, menelusuri kembali langkah-langkah untuk menjelajahi jalur alternatif melalui konten pencarian.

Meskipun ini adalah kasus penggunaan umum, ini bukan struktur navigasi tersaring yang saat ini menyediakan struktur siap pakai. Pengembang yang menginginkan aspek statik biasanya bekerja di sekitar batasan dengan mengeluarkan dua kueri yang difilter: satu tercakup ke hasil, yang lain digunakan untuk membuat daftar statik faset untuk tujuan navigasi.

Faset yang jelas

Saat Anda mendesain halaman hasil pencarian, ingatlah untuk menambahkan mekanisme untuk membersihkan faset. Jika Anda menambahkan kotak centang, Anda dapat dengan mudah melihat cara membersihkan filter. Untuk tata letak lain, Anda mungkin memerlukan pola breadcrumb atau pendekatan kreatif lainnya. Di sampel hotel C#, Anda dapat mengirim pencarian kosong untuk mereset halaman. Sebaliknya, aplikasi sampel NYCJobs menyediakan [X] yang dapat diklik setelah faset yang dipilih untuk menghapus faset, yang merupakan antrean visual yang lebih kuat kepada pengguna.

Memangkas hasil faset dengan lebih banyak filter

Hasil faset adalah dokumen yang ditemukan dalam hasil pencarian yang cocok dengan istilah faset. Dalam contoh berikut, dalam hasil pencarian untuk komputasi cloud, 254 item juga memiliki spesifikasi internal sebagai jenis konten. Item tidak selalu saling eksklusif. Jika item memenuhi kriteria kedua filter, item dihitung di masing-masing filter. Duplikasi ini dimungkinkan saat melakukan faset pada bidang Collection(Edm.String), yang sering digunakan untuk mengimplementasikan pemberian tag dokumen.

Search term: "cloud computing"
Content type
   Internal specification (254)
   Video (10)

Secara umum, jika Anda mendapati bahwa hasil faset secara konsisten terlalu besar, sebaiknya Anda menambahkan lebih banyak filter untuk memberi pengguna lebih banyak opsi untuk mempersempit pencarian.

Pengalaman pencarian hanya faset

Jika aplikasi Anda menggunakan navigasi tersaring secara eksklusif (yaitu tidak ada kotak pencarian), Anda dapat menandai bidang sebagai searchable=false, filterable=true, facetable=true untuk menghasilkan indeks yang lebih ringkas. Indeks Anda tidak akan menyertakan indeks terbalik dan tidak ada analisis teks atau tokenisasi selama pengindeksan. Filter dibuat pada pertandingan yang tepat pada tingkat karakter.

Memvalidasi input pada waktu kueri

Jika Anda membangun daftar faset secara dinamis berdasarkan input pengguna yang tidak tepercaya, validasikan bahwa nama bidang faset valid. Atau, beri karakter escape pada nama saat membuat URL menggunakan Uri.EscapeDataString() di .NET, atau yang setara di platform pilihan Anda.

Sampel

Kami merekomendasikan sampel berikut untuk navigasi tersaring. Sampel juga mencakup filter, saran, dan lengkapi otomatis. Sampel ini menggunakan React untuk lapisan presentasi.