Tutorial: Tambahkan lengkapiotomatis dan saran menggunakan .NET SDK

Pelajari cara menerapkan lengkapiotomatis (kueri typeahead dan hasil yang disarankan) saat pengguna mulai mengetik di dalam kotak pencarian. Dalam tutorial ini, kita akan menampilkan kueri yang lengkapi otomatis dan hasil yang disarankan secara terpisah, lalu bersama-sama. Pengguna mungkin hanya perlu mengetik dua atau tiga karakter untuk menemukan semua hasil yang tersedia.

Dalam tutorial ini, Anda akan mempelajari cara:

  • Tambahkan saran
  • Tambahkan penyorotan ke saran
  • Tambahkan lengkapiotomatis
  • Gabungkan lengkapiotomatis dan saran

Gambaran Umum

Tutorial ini menambahkan lengkapiotomatis dan hasil yang disarankan ke tutorial Tambahkan paging ke hasil pencarian sebelumnya.

Versi akhir kode dalam tutorial ini dapat ditemukan dalam proyek berikut:

Prasyarat

  • Solusi 2a-add-paging (GitHub). Proyek ini dapat berupa versi Anda sendiri yang dibuat dari tutorial sebelumnya atau salinan dari GitHub.

Tambahkan saran

Mari kita mulai dengan kasus paling sederhana untuk menawarkan alternatif kepada pengguna: daftar drop-down hasil yang disarankan.

  1. Dalam file index.cshtml, ubah @id pernyataan TextBoxFor menjadi azureautosuggest.

     @Html.TextBoxFor(m => m.searchText, new { @class = "searchBox", @id = "azureautosuggest" }) <input value="" class="searchBoxSubmit" type="submit">
    
  2. Sesuai pernyataan ini, setelah penutupan </div> , masukkan skrip ini. Skrip ini memanfaatkan widget Autocomplete dari koleksi UI jQuery open-source untuk menyajikan daftar dropdown hasil yang disarankan.

    <script>
        $("#azureautosuggest").autocomplete({
            source: "/Home/SuggestAsync?highlights=false&fuzzy=false",
            minLength: 2,
            position: {
                my: "left top",
                at: "left-23 bottom+10"
            }
        });
    </script>
    

    ID "azureautosuggest"menyambungkan skrip di atas ke kotak pencarian. Opsi sumber widget diatur ke metode Suggest yang menyebutkan API Saran dengan dua parameter kueri: sorotan dan fuzzy, keduanya diatur ke salah dalam contoh ini. Selain itu, minimal dua karakter diperlukan untuk mempercepat pencarian.

Tambahkan referensi ke skrip jQuery ke tampilan

  1. Untuk mengakses koleksi jQuery, ubah bagian <kepala> file tampilan menjadi kode berikut:

    <head>
        <meta charset="utf-8">
        <title>Typeahead</title>
        <link href="https://code.jquery.com/ui/1.12.1/themes/start/jquery-ui.css"
              rel="stylesheet">
        <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
        <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    
        <link rel="stylesheet" href="~/css/hotels.css" />
    </head>
    
  2. Karena kami memperkenalkan referensi jQuery baru, kami juga perlu menghapus, atau mengomentari, referensi jQuery default dalam file _Layout.cshtml (di folder Views/Shared ). Temukan baris berikut, dan komentari baris skrip pertama seperti yang diperlihatkan. Perubahan ini menghindari referensi bentrok ke jQuery.

    <environment include="Development">
        <!-- <script src="~/lib/jquery/dist/jquery.js"></script> -->
        <script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
        <script src="~/js/site.js" asp-append-version="true"></script>
    </environment>
    

    Sekarang kita dapat menggunakan fungsi jQuery Lengkapiotomatis yang telah ditentukan.

Tambahkan tindakan Sarankan ke pengontrol

  1. Di pengontrol beranda, tambahkan tindakan SuggestAsync (setelah tindakan PageAsync) .

    public async Task<ActionResult> SuggestAsync(bool highlights, bool fuzzy, string term)
    {
        InitSearch();
    
        // Setup the suggest parameters.
        var options = new SuggestOptions()
        {
            UseFuzzyMatching = fuzzy,
            Size = 8,
        };
    
        if (highlights)
        {
            options.HighlightPreTag = "<b>";
            options.HighlightPostTag = "</b>";
        }
    
        // Only one suggester can be specified per index. It is defined in the index schema.
        // The name of the suggester is set when the suggester is specified by other API calls.
        // The suggester for the hotel database is called "sg", and simply searches the hotel name.
        var suggestResult = await _searchClient.SuggestAsync<Hotel>(term, "sg", options).ConfigureAwait(false);
    
        // Convert the suggested query results to a list that can be displayed in the client.
        List<string> suggestions = suggestResult.Value.Results.Select(x => x.Text).ToList();
    
        // Return the list of suggestions.
        return new JsonResult(suggestions);
    }
    

    Parameter Ukuran menentukan berapa banyak hasil yang akan dikembalikan (jika tidak ditentukan, default-nya adalah 5). Pemberi saran ditentukan pada indeks pencarian saat indeks dibuat. Dalam indeks hotel contoh yang diselenggarakan oleh Microsoft, nama yang disarankan adalah "sg", dan mencari kecocokan yang disarankan secara eksklusif di bidang HotelName.

    Pencocokan fuzzy memungkinkan "hampir terlewat" untuk dimasukkan dalam output, hingga satu jarak edit. Jika parameter sorotan diatur ke benar, maka tag HTML bercetak tebal ditambahkan ke output. Kami akan mengatur kedua parameter ke true di bagian berikutnya.

  2. Anda mungkin akan menemukan beberapa kesalahan sintaks. Jika demikian, tambahkan dua pernyataan berikut ke bagian atas file.

    using System.Collections.Generic;
    using System.Linq;
    
  3. Jalankan aplikasi. Apakah Anda mendapatkan berbagai opsi saat memasukkan "po", misalnya? Sekarang coba "pa".

    Mengetik *po* akan menampilkan dua saran

    Perhatikan bahwa huruf yang Anda masukkan harus memulai kata, dan tidak hanya disertakan dalam kata.

  4. Di skrip tampilan, atur &fuzzy ke benar, dan jalankan aplikasi lagi. Sekarang masukkan "po". Perhatikan bahwa pencarian mengasumsikan Anda mendapatkan satu huruf salah.

    Mengetik *pa* dengan fuzzy diatur ke benar

    Jika Anda tertarik, sintaks kueri Lucene dalam Azure Cognitive Search menjelaskan logika yang digunakan dalam pencarian fuzzy secara rinci.

Tambahkan penyorotan ke saran

Tampilan saran kepada pengguna dapat ditingkatkan dengan mengatur parameter sorotan ke benar. Namun, pertama-tama kita perlu menambahkan beberapa kode ke tampilan untuk menampilkan teks yang dicetak tebal.

  1. Dalam tampilan (index.cshtml), tambahkan skrip berikut setelah "azureautosuggest" skrip yang dijelaskan sebelumnya.

    <script>
        var updateTextbox = function (event, ui) {
            var result = ui.item.value.replace(/<\/?[^>]+(>|$)/g, "");
            $("#azuresuggesthighlights").val(result);
            return false;
        };
    
        $("#azuresuggesthighlights").autocomplete({
            html: true,
            source: "/home/suggest?highlights=true&fuzzy=false&",
            minLength: 2,
            position: {
                my: "left top",
                at: "left-23 bottom+10"
            },
            select: updateTextbox,
            focus: updateTextbox
        }).data("ui-autocomplete")._renderItem = function (ul, item) {
            return $("<li></li>")
                .data("item.autocomplete", item)
                .append("<a>" + item.label + "</a>")
                .appendTo(ul);
        };
    </script>
    
  2. Sekarang ubah ID kotak teks sehingga berbunyi sebagai berikut.

    @Html.TextBoxFor(m => m.searchText, new { @class = "searchBox", @id = "azuresuggesthighlights" }) <input value="" class="searchBoxSubmit" type="submit">
    
  3. Jalankan aplikasi lagi, dan Anda akan melihat teks bercetak tebal yang Anda masukkan ke dalam saran. Coba ketik "pa".

    Mengetik *pa* dengan penyorotan

    Logika yang digunakan dalam skrip penyorotan di atas tidak mudah. Jika Anda memasukkan istilah yang muncul dua kali dengan nama yang sama, hasil tebal tidak seperti yang Anda inginkan. Coba ketik "mo".

    Salah satu pertanyaan yang perlu dijawab oleh pengembang adalah, kapan skrip bekerja dengan "cukup baik", dan kapan quirk harus ditangani. Kami tidak akan menyoroti lebih lanjut dalam tutorial ini, tetapi menemukan algoritma yang tepat adalah sesuatu yang perlu dipertimbangkan jika penyorotan tidak efektif untuk data Anda. Untuk informasi selengkapnya, lihat Tekan penyorotan.

Tambahkan lengkapiotomatis

Variasi lain, sedikit berbeda dari saran, adalah lengkapiotomatis (kadang-kadang disebut "type-ahead") yang melengkapi istilah kueri. Sekali lagi, kita akan mulai dengan implementasi yang paling sederhana, sebelum meningkatkan pengalaman pengguna.

  1. Masukkan skrip berikut ke dalam tampilan, mengikuti skrip Anda sebelumnya.

    <script>
        $("#azureautocompletebasic").autocomplete({
            source: "/Home/Autocomplete",
            minLength: 2,
            position: {
                my: "left top",
                at: "left-23 bottom+10"
            }
        });
    </script>
    
  2. Sekarang ubah ID kotak teks sehingga berbunyi sebagai berikut.

    @Html.TextBoxFor(m => m.searchText, new { @class = "searchBox", @id = "azureautocompletebasic" }) <input value="" class="searchBoxSubmit" type="submit">
    
  3. Di pengontrol rumah, masukkan tindakan AutocompleteAsync setelah tindakan SuggestAsync.

    public async Task<ActionResult> AutoCompleteAsync(string term)
    {
        InitSearch();
    
        // Setup the autocomplete parameters.
        var ap = new AutocompleteOptions()
        {
            Mode = AutocompleteMode.OneTermWithContext,
            Size = 6
        };
        var autocompleteResult = await _searchClient.AutocompleteAsync(term, "sg", ap).ConfigureAwait(false);
    
        // Convert the autocompleteResult results to a list that can be displayed in the client.
        List<string> autocomplete = autocompleteResult.Value.Results.Select(x => x.Text).ToList();
    
        return new JsonResult(autocomplete);
    }
    

    Perhatikan bahwa kami menggunakan fungsi pemberi saran yang sama, yang disebut "sg", dalam pencarian lengkapi otomatis seperti yang kami lakukan untuk saran (jadi kami hanya mencoba untuk melengkapi nama hotel secara otomatis).

    Ada berbagai pengaturan AutocompleteMode , dan kami menggunakan OneTermWithContext. Lihat API Lengkapiotomatis untuk mendapatkan deskripsi opsi tambahan.

  4. Jalankan aplikasi. Perhatikan bagaimana rentang opsi yang ditampilkan dalam daftar drop-down adalah satu kata. Coba ketik kata-kata yang dimulai dengan "re". Perhatikan bagaimana jumlah opsi berkurang karena lebih banyak huruf diketik.

    Mengetik dengan lengkapiotomatis dasar

    Sebagaimana adanya, skrip saran yang Anda jalankan sebelumnya mungkin lebih membantu daripada skrip lengkapiotomatis ini. Untuk membuat lengkapiotomatis lebih ramah pengguna, gunakan dengan hasil yang disarankan.

Gabungkan lengkapiotomatis dan saran

Menggabungkan lengkapiotomatis dan saran adalah opsi yang paling kompleks dari kami, dan mungkin akan memberikan pengalaman terbaik bagi pengguna. Kami ingin menampilkan, sesuai dengan teks yang sedang diketik, pilihan pertama Azure Cognitive Search untuk melengkapi teks secara otomatis. Selain itu, kami menginginkan berbagai saran sebagai daftar drop-down.

Ada koleksi yang menawarkan fungsionalitas ini - sering disebut "inline autocompletion" atau nama yang sama. Namun, kami akan menerapkan fitur ini secara asli sehingga Anda dapat menjelajahi API. Kita akan mulai bekerja pada pengontrol terlebih dahulu dalam contoh ini.

  1. Tambahkan tindakan ke pengontrol yang hanya mengembalikan satu hasil lengkapiotomatis, beserta sejumlah saran yang ditentukan. Kami akan memanggil tindakan ini AutoCompleteAndSuggestAsync. Di pengontrol rumah, tambahkan tindakan berikut, ikuti tindakan baru Anda yang lain.

    public async Task<ActionResult> AutoCompleteAndSuggestAsync(string term)
    {
        InitSearch();
    
        // Setup the type-ahead search parameters.
        var ap = new AutocompleteOptions()
        {
            Mode = AutocompleteMode.OneTermWithContext,
            Size = 1,
        };
        var autocompleteResult = await _searchClient.AutocompleteAsync(term, "sg", ap);
    
        // Setup the suggest search parameters.
        var sp = new SuggestOptions()
        {
            Size = 8,
        };
    
        // Only one suggester can be specified per index. The name of the suggester is set when the suggester is specified by other API calls.
        // The suggester for the hotel database is called "sg" and simply searches the hotel name.
        var suggestResult = await _searchClient.SuggestAsync<Hotel>(term, "sg", sp).ConfigureAwait(false);
    
        // Create an empty list.
        var results = new List<string>();
    
        if (autocompleteResult.Value.Results.Count > 0)
        {
            // Add the top result for type-ahead.
            results.Add(autocompleteResult.Value.Results[0].Text);
        }
        else
        {
            // There were no type-ahead suggestions, so add an empty string.
            results.Add("");
        }
    
        for (int n = 0; n < suggestResult.Value.Results.Count; n++)
        {
            // Now add the suggestions.
            results.Add(suggestResult.Value.Results[n].Text);
        }
    
        // Return the list.
        return new JsonResult(results);
    }
    

    Satu opsi lengkapiotomatis dikembalikan di bagian atas daftar hasil, diikuti oleh semua saran.

  2. Dalam tampilan, pertama-tama kami menerapkan trik sehingga kata lengkapiotomatis abu-abu muda dirender tepat di bawah teks bercetak tebal yang dimasukkan oleh pengguna. HTML menyertakan posisi relatif untuk tujuan ini. Ubah pernyataan TextBoxFor (dan pernyataan <div > sekitarnya) ke yang berikut ini, mengingat bahwa kotak pencarian kedua yang diidentifikasi sebagai di bawahnya berada tepat di bawah kotak pencarian normal kami, dengan menarik 39 piksel di kotak pencarian ini dari lokasi defaultnya!

    <div id="underneath" class="searchBox" style="position: relative; left: 0; top: 0">
    </div>
    
    <div id="searchinput" class="searchBoxForm" style="position: relative; left: 0; top: -39px">
        @Html.TextBoxFor(m => m.searchText, new { @class = "searchBox", @id = "azureautocomplete" }) <input value="" class="searchBoxSubmit" type="submit">
    </div>
    

    Perhatikan bahwa kami mengubah ID lagi, ke azureautocomplete dalam kasus ini.

  3. Juga dalam tampilan, masukkan skrip berikut, setelah semua skrip yang Anda masukkan sejauh ini. Skripnya panjang dan kompleks karena berbagai perilaku input yang ditanganinya.

    <script>
        $('#azureautocomplete').autocomplete({
            delay: 500,
            minLength: 2,
            position: {
                my: "left top",
                at: "left-23 bottom+10"
            },
    
            // Use Ajax to set up a "success" function.
            source: function (request, response) {
                var controllerUrl = "/Home/AutoCompleteAndSuggestAsync?term=" + $("#azureautocomplete").val();
                $.ajax({
                    url: controllerUrl,
                    dataType: "json",
                    success: function (data) {
                        if (data && data.length > 0) {
    
                            // Show the autocomplete suggestion.
                            document.getElementById("underneath").innerHTML = data[0];
    
                            // Remove the top suggestion as it is used for inline autocomplete.
                            var array = new Array();
                            for (var n = 1; n < data.length; n++) {
                                array[n - 1] = data[n];
                            }
    
                            // Show the drop-down list of suggestions.
                            response(array);
                        } else {
    
                            // Nothing is returned, so clear the autocomplete suggestion.
                            document.getElementById("underneath").innerHTML = "";
                        }
                    }
                });
            }
        });
    
        // Complete on TAB.
        // Clear on ESC.
        // Clear if backspace to less than 2 characters.
        // Clear if any arrow key hit as user is navigating the suggestions.
        $("#azureautocomplete").keydown(function (evt) {
    
            var suggestedText = document.getElementById("underneath").innerHTML;
            if (evt.keyCode === 9 /* TAB */ && suggestedText.length > 0) {
                $("#azureautocomplete").val(suggestedText);
                return false;
            } else if (evt.keyCode === 27 /* ESC */) {
                document.getElementById("underneath").innerHTML = "";
                $("#azureautocomplete").val("");
            } else if (evt.keyCode === 8 /* Backspace */) {
                if ($("#azureautocomplete").val().length < 2) {
                    document.getElementById("underneath").innerHTML = "";
                }
            } else if (evt.keyCode >= 37 && evt.keyCode <= 40 /* Any arrow key */) {
                document.getElementById("underneath").innerHTML = "";
            }
        });
    
        // Character replace function.
        function setCharAt(str, index, chr) {
            if (index > str.length - 1) return str;
            return str.substr(0, index) + chr + str.substr(index + 1);
        }
    
        // This function is needed to clear the "underneath" text when the user clicks on a suggestion, and to
        // correct the case of the autocomplete option when it does not match the case of the user input.
        // The interval function is activated with the input, blur, change, or focus events.
        $("#azureautocomplete").on("input blur change focus", function (e) {
    
            // Set a 2 second interval duration.
            var intervalDuration = 2000, 
                interval = setInterval(function () {
    
                    // Compare the autocorrect suggestion with the actual typed string.
                    var inputText = document.getElementById("azureautocomplete").value;
                    var autoText = document.getElementById("underneath").innerHTML;
    
                    // If the typed string is longer than the suggestion, then clear the suggestion.
                    if (inputText.length > autoText.length) {
                        document.getElementById("underneath").innerHTML = "";
                    } else {
    
                        // If the strings match, change the case of the suggestion to match the case of the typed input.
                        if (autoText.toLowerCase().startsWith(inputText.toLowerCase())) {
                            for (var n = 0; n < inputText.length; n++) {
                                autoText = setCharAt(autoText, n, inputText[n]);
                            }
                            document.getElementById("underneath").innerHTML = autoText;
    
                        } else {
                            // The strings do not match, so clear the suggestion.
                            document.getElementById("underneath").innerHTML = "";
                        }
                    }
    
                    // If the element loses focus, stop the interval checking.
                    if (!$input.is(':focus')) clearInterval(interval);
    
                }, intervalDuration);
        });
    </script>
    

    Perhatikan bagaimana fungsi interval digunakan untuk menghapus teks bergaris bawah ketika tidak lagi cocok dengan apa yang diketik pengguna, dan juga untuk mengatur kasus yang sama (atas atau bawah) karena pengguna mengetik ("pa" cocok dengan "PA", "pA", "Pa" saat mencari), sehingga teks tersembunyi tampak rapi.

    Baca komentar dalam skrip untuk mendapatkan pemahaman menyeluruh.

  4. Akhirnya, kita perlu membuat penyesuaian kecil pada dua kelas HTML untuk membuatnya transparan. Tambahkan baris berikut ke kelas searchBoxForm dan searchBox, di file hotel.css.

    background: rgba(0,0,0,0);
    
  5. Sekarang jalankan aplikasi. Masukkan "pa" ke dalam kotak pencarian. Apakah Anda mendapatkan "palace" sebagai saran lengkapiotomatis, beserta dua hotel yang berisi "pa"?

    Mengetik dengan lengkapiotomatis dan saran sebaris

  6. Coba ketuk untuk menerima saran lengkapiotomatis, dan coba pilih saran menggunakan tombol panah dan tombol tab lalu coba lagi menggunakan mouse dan klik sekali. Verifikasi bahwa skrip menangani situasi ini dengan rapi.

    Anda dapat memutuskan bahwa lebih mudah untuk memuat di pustaka yang menawarkan fitur ini untuk Anda, tetapi sekarang Anda tahu setidaknya satu cara agar pelengkapan otomatis sebaris berfungsi.

Takeaway

Pertimbangkan takeaway berikut dari proyek ini:

  • Lengkapiotomatis (juga dikenal sebagai "type-ahead") dan saran memungkinkan pengguna mengetik hanya beberapa kunci untuk menemukan apa yang mereka cari.
  • Kerja sama lengkapiotomatis dan saran dapat meningkatkan pengalaman pengguna.
  • Selalu uji fungsi lengkapiotomatis dengan semua bentuk input.
  • Penggunaan fungsi setInterval dapat membantu proses verifikasi dan koreksi elemen UI.

Langkah berikutnya

Dalam tutorial berikutnya, kita menggunakan cara lain untuk meningkatkan pengalaman pengguna, yaitu menggunakan aspek untuk mempersempit pencarian dengan satu klik.