Tutorial: Memesan hasil pencarian menggunakan .NET SDK

Sepanjang seri tutorial ini, hasil telah dikembalikan dan ditampilkan dalam urutan default. Dalam tutorial ini, Anda akan menambahkan kriteria pengurutan primer dan sekunder. Sebagai alternatif untuk mengurutkan berdasarkan nilai numerik, contoh akhir menunjukkan cara memberi peringkat hasil berdasarkan profil penilaian kustom. Kami juga akan menggali lebih dalam dalam tampilan jenis kompleks.

Dalam tutorial ini, Anda akan belajar cara:

  • Urutkan hasil berdasarkan satu properti
  • Urutkan hasil berdasarkan beberapa properti
  • Mengurutkan hasil berdasarkan profil penilaian

Gambaran Umum

Tutorial ini memperluas proyek pengguliran tak terbatas yang dibuat dalam tutorial Tambahkan halaman ke hasil pencarian .

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

Prasyarat

  • 2b-add-infinite-scroll (GitHub) merupakan solusi. Proyek ini dapat berupa versi Anda sendiri yang dibangun dari tutorial sebelumnya atau salinan dari GitHub.

Urutkan hasil berdasarkan satu properti

Saat memesan hasil berdasarkan satu properti, seperti peringkat hotel, kami tidak hanya menginginkan hasil yang dipesan, kami juga ingin konfirmasi bahwa pesanan sudah benar. Menambahkan bidang Peringkat ke hasil memungkinkan kami mengonfirmasi bahwa hasilnya diurutkan dengan benar.

Dalam latihan ini, kami juga akan menambahkan sedikit lebih ke tampilan hasil: tarif kamar termurah, dan tarif kamar paling mahal, untuk setiap hotel.

Tidak perlu memodifikasi salah satu model untuk mengaktifkan pemesanan. Hanya tampilan dan pengontrol yang memerlukan pembaruan. Mulailah dengan membuka pengontrol rumah.

Menambahkan properti OrderBy ke parameter pencarian

  1. Di HomeController.cs, tambahkan opsi OrderBy dan sertakan properti Peringkat, dengan urutan pengurutan turun. Dalam metode Index(Model SearchData), tambahkan baris berikut ke parameter pencarian.

    options.OrderBy.Add("Rating desc");
    

    Nota

    Urutan default adalah naik, meskipun Anda dapat menambahkan asc ke properti untuk memperjelas ini. Urutan turun ditentukan dengan menambahkan desc.

  2. Sekarang jalankan aplikasi, dan masukkan istilah pencarian umum apa pun. Hasilnya mungkin atau mungkin tidak dalam urutan yang benar, karena Anda sebagai pengembang, bukan pengguna, tidak memiliki cara mudah untuk memverifikasi hasilnya!

  3. Mari kita perjelas hasilnya diurutkan pada peringkat. Pertama, ganti kelas box1 dan box2 dalam file hotels.css dengan kelas berikut (kelas-kelas ini adalah kelas baru yang kita butuhkan untuk tutorial ini).

    textarea.box1A {
        width: 324px;
        height: 32px;
        border: none;
        background-color: azure;
        font-size: 14pt;
        color: blue;
        padding-left: 5px;
        text-align: left;
    }
    
    textarea.box1B {
        width: 324px;
        height: 32px;
        border: none;
        background-color: azure;
        font-size: 14pt;
        color: blue;
        text-align: right;
        padding-right: 5px;
    }
    
    textarea.box2A {
        width: 324px;
        height: 32px;
        border: none;
        background-color: azure;
        font-size: 12pt;
        color: blue;
        padding-left: 5px;
        text-align: left;
    }
    
    textarea.box2B {
        width: 324px;
        height: 32px;
        border: none;
        background-color: azure;
        font-size: 12pt;
        color: blue;
        text-align: right;
        padding-right: 5px;
    }
    
    textarea.box3 {
        width: 648px;
        height: 100px;
        border: none;
        background-color: azure;
        font-size: 12pt;
        padding-left: 5px;
        margin-bottom: 24px;
    }
    

    Petunjuk / Saran

    Browser biasanya menyimpan file css, dan ini dapat menyebabkan file css lama digunakan, dan pengeditan Anda diabaikan. Cara solusi yang baik adalah menambahkan string kueri dengan parameter versi ke tautan. Contohnya:

      <link rel="stylesheet" href="~/css/hotels.css?v1.1" />
    

    Perbarui nomor versi jika Anda merasa file css lama sedang digunakan oleh browser Anda.

  4. Tambahkan properti Peringkat ke parameter Pilih , dalam metode Indeks(model SearchData) sehingga hasilnya menyertakan tiga bidang berikut:

    options.Select.Add("HotelName");
    options.Select.Add("Description");
    options.Select.Add("Rating");
    
  5. Buka tampilan (index.cshtml) dan ganti perulangan penyajian (<-- Tampilkan data hotel. -->) dengan kode berikut.

    <!-- Show the hotel data. -->
    @for (var i = 0; i < result.Count; i++)
    {
        var ratingText = $"Rating: {result[i].Document.Rating}";
    
        // Display the hotel details.
        @Html.TextArea($"name{i}", result[i].Document.HotelName, new { @class = "box1A" })
        @Html.TextArea($"rating{i}", ratingText, new { @class = "box1B" })
        @Html.TextArea($"desc{i}", fullDescription, new { @class = "box3" })
    }
    
  6. Peringkat harus tersedia baik di halaman pertama yang ditampilkan maupun di halaman berikutnya yang dipanggil melalui scroll tidak terbatas. Untuk kedua situasi ini, kita perlu memperbarui tindakan Berikutnya di pengontrol, dan fungsi yang digulirkan dalam tampilan. Dimulai dengan pengontrol, ubah metode Berikutnya ke kode berikut. Kode ini membuat dan mengkomunikasikan teks peringkat.

    public async Task<ActionResult> Next(SearchData model)
    {
        // Set the next page setting, and call the Index(model) action.
        model.paging = "next";
        await Index(model);
    
        // Create an empty list.
        var nextHotels = new List<string>();
    
        // Add a hotel details to the list.
        await foreach (var result in model.resultList.GetResultsAsync())
        {
            var ratingText = $"Rating: {result.Document.Rating}";
            var rateText = $"Rates from ${result.Document.cheapest} to ${result.Document.expensive}";
    
            string fullDescription = result.Document.Description;
    
            // Add strings to the list.
            nextHotels.Add(result.Document.HotelName);
            nextHotels.Add(ratingText);
            nextHotels.Add(fullDescription);
        }
    
        // Rather than return a view, return the list of data.
        return new JsonResult(nextHotels);
    }
    
  7. Sekarang perbarui fungsi yang digulir dalam tampilan, untuk menampilkan teks peringkat.

    <script>
        function scrolled() {
            if (myDiv.offsetHeight + myDiv.scrollTop >= myDiv.scrollHeight) {
                $.getJSON("/Home/Next", function (data) {
                    var div = document.getElementById('myDiv');
    
                    // Append the returned data to the current list of hotels.
                    for (var i = 0; i < data.length; i += 3) {
                        div.innerHTML += '\n<textarea class="box1A">' + data[i] + '</textarea>';
                        div.innerHTML += '\n<textarea class="box1B">' + data[i + 1] + '</textarea>';
                        div.innerHTML += '\n<textarea class="box3">' + data[i + 2] + '</textarea>';
                    }
                });
            }
        }
    </script>
    
  8. Sekarang jalankan aplikasi lagi. Cari pada istilah umum apa pun, seperti "wifi", dan verifikasi bahwa hasilnya diurutkan berdasarkan urutan peringkat hotel turun.

    Pemesanan berdasarkan peringkat

    Anda akan melihat bahwa beberapa hotel memiliki peringkat yang identik, sehingga penampilan mereka di tampilan mengikuti urutan data yang ditemukan, yang acak.

    Sebelum kita melihat penambahan tingkat pemesanan kedua, mari kita tambahkan beberapa kode untuk menampilkan rentang tarif kamar. Kami menambahkan kode ini untuk menunjukkan mengekstrak data dari jenis yang kompleks, dan juga sehingga kita dapat mendiskusikan hasil pemesanan berdasarkan harga (termurah terlebih dahulu mungkin).

Tambahkan rentang tarif kamar ke tampilan

  1. Tambahkan properti yang berisi tarif kamar termurah dan termahal ke model Hotel.cs.

    // Room rate range
    public double cheapest { get; set; }
    public double expensive { get; set; }
    
  2. Hitung tarif kamar di akhir tindakan Index(SearchData model), di pengendali utama. Tambahkan perhitungan setelah penyimpanan data sementara.

    // Ensure TempData is stored for the next call.
    TempData["page"] = page;
    TempData["searchfor"] = model.searchText;
    
    // Calculate the room rate ranges.
    await foreach (var result in model.resultList.GetResultsAsync())
    {
        var cheapest = 0d;
        var expensive = 0d;
    
        foreach (var room in result.Document.Rooms)
        {
            var rate = room.BaseRate;
            if (rate < cheapest || cheapest == 0)
            {
                cheapest = (double)rate;
            }
            if (rate > expensive)
            {
                expensive = (double)rate;
            }
        }
        model.resultList.Results[n].Document.cheapest = cheapest;
        model.resultList.Results[n].Document.expensive = expensive;
    }
    
  3. Tambahkan properti Kamar ke parameter Pilih dalam metode tindakan Indeks (model SearchData) pengontrol.

    options.Select.Add("Rooms");
    
  4. Ubah perulangan penyajian dalam tampilan untuk menampilkan rentang laju untuk halaman pertama hasil.

    <!-- Show the hotel data. -->
    @for (var i = 0; i < result.Count; i++)
    {
        var rateText = $"Rates from ${result[i].Document.cheapest} to ${result[i].Document.expensive}";
        var ratingText = $"Rating: {result[i].Document.Rating}";
    
        string fullDescription = result[i].Document.Description;
    
        // Display the hotel details.
        @Html.TextArea($"name{i}", result[i].Document.HotelName, new { @class = "box1A" })
        @Html.TextArea($"rating{i}", ratingText, new { @class = "box1B" })
        @Html.TextArea($"rates{i}", rateText, new { @class = "box2A" })
        @Html.TextArea($"desc{i}", fullDescription, new { @class = "box3" })
    }
    
  5. Ubah metode Berikutnya di pengontrol rumah untuk mengomunikasikan rentang laju, untuk halaman hasil berikutnya.

    public async Task<ActionResult> Next(SearchData model)
    {
        // Set the next page setting, and call the Index(model) action.
        model.paging = "next";
        await Index(model);
    
        // Create an empty list.
        var nextHotels = new List<string>();
    
        // Add a hotel details to the list.
        await foreach (var result in model.resultList.GetResultsAsync())
        {
            var ratingText = $"Rating: {result.Document.Rating}";
            var rateText = $"Rates from ${result.Document.cheapest} to ${result.Document.expensive}";
    
            string fullDescription = result.Document.Description;
    
            // Add strings to the list.
            nextHotels.Add(result.Document.HotelName);
            nextHotels.Add(ratingText);
            nextHotels.Add(rateText);
            nextHotels.Add(fullDescription);
        }
    
        // Rather than return a view, return the list of data.
        return new JsonResult(nextHotels);
    }
    
  6. Perbarui fungsi yang digulir dalam tampilan, untuk menangani teks tarif kamar.

    <script>
        function scrolled() {
            if (myDiv.offsetHeight + myDiv.scrollTop >= myDiv.scrollHeight) {
                $.getJSON("/Home/Next", function (data) {
                    var div = document.getElementById('myDiv');
    
                    // Append the returned data to the current list of hotels.
                    for (var i = 0; i < data.length; i += 4) {
                        div.innerHTML += '\n<textarea class="box1A">' + data[i] + '</textarea>';
                        div.innerHTML += '\n<textarea class="box1B">' + data[i + 1] + '</textarea>';
                        div.innerHTML += '\n<textarea class="box2A">' + data[i + 2] + '</textarea>';
                        div.innerHTML += '\n<textarea class="box3">' + data[i + 4] + '</textarea>';
                    }
                });
            }
        }
    </script>
    
  7. Jalankan aplikasi, dan verifikasi rentang tarif kamar ditampilkan.

    Menampilkan rentang tarif kamar

Properti OrderBy dari parameter pencarian tidak akan menerima entri seperti Rooms.BaseRate untuk memberikan tarif kamar termurah, bahkan jika kamar sudah diurutkan berdasarkan tarif. Dalam hal ini, kamar tidak diurutkan berdasarkan tarif. Untuk menampilkan hotel dalam himpunan data sampel, yang diurutkan berdasarkan tarif kamar, Anda harus mengurutkan hasilnya di pengontrol rumah Anda, dan mengirim hasil ini ke tampilan dalam urutan yang diinginkan.

Hasil pesanan berdasarkan beberapa nilai

Pertanyaannya sekarang adalah bagaimana membedakan antara hotel dengan peringkat yang sama. Salah satu pendekatan mungkin merupakan pemesanan sekunder berdasarkan terakhir kali hotel direnovasi sehingga hotel yang baru saja direnovasi muncul lebih tinggi dalam hasilnya.

  1. Untuk menambahkan tingkat urutan kedua, tambahkan LastRenovationDate ke hasil pencarian dan ke OrderBy dalam metode Indeks (model SearchData).

    options.Select.Add("LastRenovationDate");
    
    options.OrderBy.Add("LastRenovationDate desc");
    

    Petunjuk / Saran

    Sejumlah properti dapat dimasukkan dalam daftar OrderBy . Jika hotel memiliki peringkat dan tanggal renovasi yang sama, properti ketiga dapat dimasukkan untuk membedakannya.

  2. Sekali lagi, kita perlu melihat tanggal renovasi dalam tampilan, hanya untuk memastikan pemesanan sudah benar. Untuk hal seperti renovasi, mungkin hanya setahun sudah cukup. Ubah perulangan penyajian dalam tampilan ke kode berikut.

    <!-- Show the hotel data. -->
    @for (var i = 0; i < result.Count; i++)
    {
        var rateText = $"Rates from ${result[i].Document.cheapest} to ${result[i].Document.expensive}";
        var lastRenovatedText = $"Last renovated: { result[i].Document.LastRenovationDate.Value.Year}";
        var ratingText = $"Rating: {result[i].Document.Rating}";
    
        string fullDescription = result[i].Document.Description;
    
        // Display the hotel details.
        @Html.TextArea($"name{i}", result[i].Document.HotelName, new { @class = "box1A" })
        @Html.TextArea($"rating{i}", ratingText, new { @class = "box1B" })
        @Html.TextArea($"rates{i}", rateText, new { @class = "box2A" })
        @Html.TextArea($"renovation{i}", lastRenovatedText, new { @class = "box2B" })
        @Html.TextArea($"desc{i}", fullDescription, new { @class = "box3" })
    }
    
  3. Ubah metode Berikutnya di pengontrol rumah, untuk meneruskan komponen tahun dari tanggal renovasi terakhir.

        public async Task<ActionResult> Next(SearchData model)
        {
            // Set the next page setting, and call the Index(model) action.
            model.paging = "next";
            await Index(model);
    
            // Create an empty list.
            var nextHotels = new List<string>();
    
            // Add a hotel details to the list.
            await foreach (var result in model.resultList.GetResultsAsync())
            {
                var ratingText = $"Rating: {result.Document.Rating}";
                var rateText = $"Rates from ${result.Document.cheapest} to ${result.Document.expensive}";
                var lastRenovatedText = $"Last renovated: {result.Document.LastRenovationDate.Value.Year}";
    
                string fullDescription = result.Document.Description;
    
                // Add strings to the list.
                nextHotels.Add(result.Document.HotelName);
                nextHotels.Add(ratingText);
                nextHotels.Add(rateText);
                nextHotels.Add(lastRenovatedText);
                nextHotels.Add(fullDescription);
            }
    
            // Rather than return a view, return the list of data.
            return new JsonResult(nextHotels);
        }
    
  4. Ubah fungsi bergulir di dalam tampilan untuk menampilkan teks renovasi.

    <script>
        function scrolled() {
            if (myDiv.offsetHeight + myDiv.scrollTop >= myDiv.scrollHeight) {
                $.getJSON("/Home/Next", function (data) {
                    var div = document.getElementById('myDiv');
    
                    // Append the returned data to the current list of hotels.
                    for (var i = 0; i < data.length; i += 5) {
                        div.innerHTML += '\n<textarea class="box1A">' + data[i] + '</textarea>';
                        div.innerHTML += '\n<textarea class="box1B">' + data[i + 1] + '</textarea>';
                        div.innerHTML += '\n<textarea class="box2A">' + data[i + 2] + '</textarea>';
                        div.innerHTML += '\n<textarea class="box2B">' + data[i + 3] + '</textarea>';
                        div.innerHTML += '\n<textarea class="box3">' + data[i + 4] + '</textarea>';
                    }
                });
            }
        }
    </script>
    
  5. Jalankan aplikasi. Cari kata umum, seperti "kolam" atau "pemandangan", dan verifikasi bahwa hotel dengan peringkat yang sama sekarang ditampilkan dalam urutan tanggal renovasi yang menurun.

    Pemesanan terkait tanggal renovasi

Mengurutkan hasil berdasarkan profil penilaian

Contoh yang diberikan dalam tutorial sejauh ini menunjukkan cara memesan nilai numerik (peringkat dan tanggal renovasi), memberikan urutan pemesanan yang tepat . Namun, beberapa pencarian dan data tidak mudah diperbandingkan antara dua elemen data. Untuk kueri pencarian teks lengkap, Cognitive Search menyertakan konsep peringkat. Profil penilaian dapat ditentukan untuk memengaruhi bagaimana hasil diberi peringkat, memberikan perbandingan yang lebih kompleks dan kualitatif.

Profil penilaian ditentukan dalam skema indeks. Beberapa profil penilaian telah disiapkan pada data hotel. Mari kita lihat bagaimana profil penilaian ditentukan, lalu coba tulis kode untuk mencarinya.

Bagaimana profil penilaian ditentukan

Profil penilaian ditentukan dalam indeks pencarian selama pembuatan desain. Indeks hotel baca-saja yang dihosting oleh Microsoft memiliki tiga profil penilaian. Bagian ini menjelajahi profil penilaian dan menunjukkan kepada Anda cara menggunakan fungsi dalam kode.

  1. Di bawah ini adalah profil penilaian default untuk himpunan data hotel, yang digunakan saat Anda tidak menentukan parameter OrderBy atau ScoringProfile apa pun. Profil ini meningkatkan skor untuk hotel jika teks pencarian ada di nama hotel, deskripsi, atau daftar tag (fasilitas). Perhatikan bagaimana bobot penilaian mendukung bidang tertentu. Jika teks pencarian muncul di bidang lain, tidak tercantum di bawah ini, teks tersebut akan memiliki berat 1. Jelas, semakin tinggi skor, semakin tinggi hasilnya muncul dalam tampilan.

    {
       "name": "boostByField",
       "text": {
           "weights": {
               "Tags": 3,
               "HotelName": 2,
               "Description": 1.5,
               "Description_fr": 1.5,
           }
       }
    }
    
  2. Profil penilaian alternatif berikut meningkatkan skor secara signifikan jika parameter yang disediakan mencakup satu atau beberapa daftar tag (yang kami sebut "fasilitas"). Titik kunci profil ini adalah bahwa parameter harus disediakan, berisi teks. Jika parameter kosong, atau tidak disediakan, akan memunculkan kesalahan.

    {
        "name":"boostAmenities",
        "functions":[
            {
            "fieldName":"Tags",
            "freshness":null,
            "interpolation":"linear",
            "magnitude":null,
            "distance":null,
            "tag":{
                "tagsParameter":"amenities"
            },
            "type":"tag",
            "boost":5
            }
        ],
        "functionAggregation":0
    },
    
  3. Dalam profil ketiga ini, peringkat hotel memberikan peningkatan yang signifikan pada skor. Tanggal terakhir yang direnovasi juga akan meningkatkan skor, tetapi hanya jika data tersebut jatuh dalam waktu 730 hari (2 tahun) dari tanggal saat ini.

    {
        "name":"renovatedAndHighlyRated",
        "functions":[
            {
            "fieldName":"Rating",
            "freshness":null,
            "interpolation":"linear",
            "magnitude":{
                "boostingRangeStart":0,
                "boostingRangeEnd":5,
                "constantBoostBeyondRange":false
            },
            "distance":null,
            "tag":null,
            "type":"magnitude",
            "boost":20
            },
            {
            "fieldName":"LastRenovationDate",
            "freshness":{
                "boostingDuration":"P730D"
            },
            "interpolation":"quadratic",
            "magnitude":null,
            "distance":null,
            "tag":null,
            "type":"freshness",
            "boost":10
            }
        ],
        "functionAggregation":0
    }
    

    Sekarang, mari kita lihat apakah profil ini berfungsi seperti yang kita pikir seharusnya.

Menambahkan kode ke tampilan untuk membandingkan profil

  1. Buka file index.cshtml, dan ganti bagian <isi> dengan kode berikut.

    <body>
    
    @using (Html.BeginForm("Index", "Home", FormMethod.Post))
    {
        <table>
            <tr>
                <td></td>
                <td>
                    <h1 class="sampleTitle">
                        <img src="~/images/azure-logo.png" width="80" />
                        Hotels Search - Order Results
                    </h1>
                </td>
            </tr>
            <tr>
                <td></td>
                <td>
                    <!-- Display the search text box, with the search icon to the right of it. -->
                    <div class="searchBoxForm">
                        @Html.TextBoxFor(m => m.searchText, new { @class = "searchBox" }) <input class="searchBoxSubmit" type="submit" value="">
                    </div>
    
                    <div class="searchBoxForm">
                        <b>&nbsp;Order:&nbsp;</b>
                        @Html.RadioButtonFor(m => m.scoring, "Default") Default&nbsp;&nbsp;
                        @Html.RadioButtonFor(m => m.scoring, "RatingRenovation") By numerical Rating&nbsp;&nbsp;
                        @Html.RadioButtonFor(m => m.scoring, "boostAmenities") By Amenities&nbsp;&nbsp;
                        @Html.RadioButtonFor(m => m.scoring, "renovatedAndHighlyRated") By Renovated date/Rating profile&nbsp;&nbsp;
                    </div>
                </td>
            </tr>
    
            <tr>
                <td valign="top">
                    <div id="facetplace" class="facetchecks">
    
                        @if (Model != null && Model.facetText != null)
                        {
                            <h5 class="facetheader">Amenities:</h5>
                            <ul class="facetlist">
                                @for (var c = 0; c < Model.facetText.Length; c++)
                                {
                                    <li> @Html.CheckBoxFor(m => m.facetOn[c], new { @id = "check" + c.ToString() }) @Model.facetText[c] </li>
                                }
    
                            </ul>
                        }
                    </div>
                </td>
                <td>
                    @if (Model != null && Model.resultList != null)
                    {
                        // Show the total result count.
                        <p class="sampleText">
                            @Html.DisplayFor(m => m.resultList.Count) Results <br />
                        </p>
    
                        <div id="myDiv" style="width: 800px; height: 450px; overflow-y: scroll;" onscroll="scrolled()">
    
                            <!-- Show the hotel data. -->
                            @for (var i = 0; i < Model.resultList.Results.Count; i++)
                            {
                                var rateText = $"Rates from ${Model.resultList.Results[i].Document.cheapest} to ${Model.resultList.Results[i].Document.expensive}";
                                var lastRenovatedText = $"Last renovated: { Model.resultList.Results[i].Document.LastRenovationDate.Value.Year}";
                                var ratingText = $"Rating: {Model.resultList.Results[i].Document.Rating}";
    
                                string amenities = string.Join(", ", Model.resultList.Results[i].Document.Tags);
                                string fullDescription = Model.resultList.Results[i].Document.Description;
                                fullDescription += $"\nAmenities: {amenities}";
    
                                // Display the hotel details.
                                @Html.TextArea($"name{i}", Model.resultList.Results[i].Document.HotelName, new { @class = "box1A" })
                                @Html.TextArea($"rating{i}", ratingText, new { @class = "box1B" })
                                @Html.TextArea($"rates{i}", rateText, new { @class = "box2A" })
                                @Html.TextArea($"renovation{i}", lastRenovatedText, new { @class = "box2B" })
                                @Html.TextArea($"desc{i}", fullDescription, new { @class = "box3" })
                            }
                        </div>
    
                        <script>
                            function scrolled() {
                                if (myDiv.offsetHeight + myDiv.scrollTop >= myDiv.scrollHeight) {
                                    $.getJSON("/Home/Next", function (data) {
                                        var div = document.getElementById('myDiv');
    
                                        // Append the returned data to the current list of hotels.
                                        for (var i = 0; i < data.length; i += 5) {
                                            div.innerHTML += '\n<textarea class="box1A">' + data[i] + '</textarea>';
                                            div.innerHTML += '<textarea class="box1B">' + data[i + 1] + '</textarea>';
                                            div.innerHTML += '\n<textarea class="box2A">' + data[i + 2] + '</textarea>';
                                            div.innerHTML += '<textarea class="box2B">' + data[i + 3] + '</textarea>';
                                            div.innerHTML += '\n<textarea class="box3">' + data[i + 4] + '</textarea>';
                                        }
                                    });
                                }
                            }
                        </script>
                    }
                </td>
            </tr>
        </table>
    }
    </body>
    
  2. Buka file SearchData.cs, dan ganti kelas SearchData dengan kode berikut.

    public class SearchData
    {
        public SearchData()
        {
        }
    
        // Constructor to initialize the list of facets sent from the controller.
        public SearchData(List<string> facets)
        {
            facetText = new string[facets.Count];
    
            for (int i = 0; i < facets.Count; i++)
            {
                facetText[i] = facets[i];
            }
        }
    
        // Array to hold the text for each amenity.
        public string[] facetText { get; set; }
    
        // Array to hold the setting for each amenitity.
        public bool[] facetOn { get; set; }
    
        // The text to search for.
        public string searchText { get; set; }
    
        // Record if the next page is requested.
        public string paging { get; set; }
    
        // The list of results.
        public DocumentSearchResult<Hotel> resultList;
    
        public string scoring { get; set; }       
    }
    
  3. Buka file hotels.css, dan tambahkan kelas HTML berikut.

    .facetlist {
        list-style: none;
    }
    
    .facetchecks {
        width: 250px;
        display: normal;
        color: #666;
        margin: 10px;
        padding: 5px;
    }
    
    .facetheader {
        font-size: 10pt;
        font-weight: bold;
        color: darkgreen;
    }
    

Menambahkan kode ke pengontrol untuk menentukan profil penilaian

  1. Buka file pengontrol rumah. Tambahkan pernyataan penggunaan berikut (untuk membantu membuat daftar).

    using System.Linq;
    
  2. Untuk contoh ini, kita memerlukan panggilan awal ke Indeks untuk melakukan sedikit lebih dari sekadar mengembalikan tampilan awal. Metode ini sekarang mencari hingga 20 fasilitas untuk ditampilkan dalam tampilan.

        public async Task<ActionResult> Index()
        {
            InitSearch();
    
            // Set up the facets call in the search parameters.
            SearchOptions options = new SearchOptions();
            // Search for up to 20 amenities.
            options.Facets.Add("Tags,count:20");
    
            SearchResults<Hotel> searchResult = await _searchClient.SearchAsync<Hotel>("*", options);
    
            // Convert the results to a list that can be displayed in the client.
            List<string> facets = searchResult.Facets["Tags"].Select(x => x.Value.ToString()).ToList();
    
            // Initiate a model with a list of facets for the first view.
            SearchData model = new SearchData(facets);
    
            // Save the facet text for the next view.
            SaveFacets(model, false);
    
            // Render the view including the facets.
            return View(model);
        }
    
  3. Kita memerlukan dua metode privat untuk menyimpan faset ke penyimpanan sementara, dan memulihkannya dari penyimpanan sementara dan mengisi model.

        // Save the facet text to temporary storage, optionally saving the state of the check boxes.
        private void SaveFacets(SearchData model, bool saveChecks = false)
        {
            for (int i = 0; i < model.facetText.Length; i++)
            {
                TempData["facet" + i.ToString()] = model.facetText[i];
                if (saveChecks)
                {
                    TempData["faceton" + i.ToString()] = model.facetOn[i];
                }
            }
            TempData["facetcount"] = model.facetText.Length;
        }
    
        // Recover the facet text to a model, optionally recoving the state of the check boxes.
        private void RecoverFacets(SearchData model, bool recoverChecks = false)
        {
            // Create arrays of the appropriate length.
            model.facetText = new string[(int)TempData["facetcount"]];
            if (recoverChecks)
            {
                model.facetOn = new bool[(int)TempData["facetcount"]];
            }
    
            for (int i = 0; i < (int)TempData["facetcount"]; i++)
            {
                model.facetText[i] = TempData["facet" + i.ToString()].ToString();
                if (recoverChecks)
                {
                    model.facetOn[i] = (bool)TempData["faceton" + i.ToString()];
                }
            }
        }
    
  4. Kita perlu mengatur parameter OrderBy dan ScoringProfile seperlunya. Ganti metode Indeks (model SearchData) yang ada, dengan yang berikut ini.

    public async Task<ActionResult> Index(SearchData model)
    {
        try
        {
            InitSearch();
    
            int page;
    
            if (model.paging != null && model.paging == "next")
            {
                // Recover the facet text, and the facet check box settings.
                RecoverFacets(model, true);
    
                // Increment the page.
                page = (int)TempData["page"] + 1;
    
                // Recover the search text.
                model.searchText = TempData["searchfor"].ToString();
            }
            else
            {
                // First search with text. 
                // Recover the facet text, but ignore the check box settings, and use the current model settings.
                RecoverFacets(model, false);
    
                // First call. Check for valid text input, and valid scoring profile.
                if (model.searchText == null)
                {
                    model.searchText = "";
                }
                if (model.scoring == null)
                {
                    model.scoring = "Default";
                }
                page = 0;
            }
    
            // Setup the search parameters.
            var options = new SearchOptions
            {
                SearchMode = SearchMode.All,
    
                // Skip past results that have already been returned.
                Skip = page * GlobalVariables.ResultsPerPage,
    
                // Take only the next page worth of results.
                Size = GlobalVariables.ResultsPerPage,
    
                // Include the total number of results.
                IncludeTotalCount = true,
            };
            // Select the data properties to be returned.
            options.Select.Add("HotelName");
            options.Select.Add("Description");
            options.Select.Add("Tags");
            options.Select.Add("Rooms");
            options.Select.Add("Rating");
            options.Select.Add("LastRenovationDate");
    
            List<string> parameters = new List<string>();
            // Set the ordering based on the user's radio button selection.
            switch (model.scoring)
            {
                case "RatingRenovation":
                    // Set the ordering/scoring parameters.
                    options.OrderBy.Add("Rating desc");
                    options.OrderBy.Add("LastRenovationDate desc");
                    break;
    
                case "boostAmenities":
                    {
                        options.ScoringProfile = model.scoring;
    
                        // Create a string list of amenities that have been clicked.
                        for (int a = 0; a < model.facetOn.Length; a++)
                        {
                            if (model.facetOn[a])
                            {
                                parameters.Add(model.facetText[a]);
                            }
                        }
    
                        if (parameters.Count > 0)
                        {
                            options.ScoringParameters.Add($"amenities-{ string.Join(',', parameters)}");
                        }
                        else
                        {
                            // No amenities selected, so set profile back to default.
                            options.ScoringProfile = "";
                        }
                    }
                    break;
    
                case "renovatedAndHighlyRated":
                    options.ScoringProfile = model.scoring;
                    break;
    
                default:
                    break;
            }
    
            // For efficiency, the search call should be asynchronous, so use SearchAsync rather than Search.
            model.resultList = await _searchClient.SearchAsync<Hotel>(model.searchText, options);
    
            // Ensure TempData is stored for the next call.
            TempData["page"] = page;
            TempData["searchfor"] = model.searchText;
            TempData["scoring"] = model.scoring;
            SaveFacets(model, true);
    
            // Calculate the room rate ranges.
            await foreach (var result in model.resultList.GetResultsAsync())
            {
                var cheapest = 0d;
                var expensive = 0d;
    
                foreach (var room in result.Document.Rooms)
                {
                    var rate = room.BaseRate;
                    if (rate < cheapest || cheapest == 0)
                    {
                        cheapest = (double)rate;
                    }
                    if (rate > expensive)
                    {
                        expensive = (double)rate;
                    }
                }
    
                result.Document.cheapest = cheapest;
                result.Document.expensive = expensive;
            }
        }
        catch
        {
            return View("Error", new ErrorViewModel { RequestId = "1" });
        }
    
        return View("Index", model);
    }
    

    Baca komentar untuk setiap pilihan pengalihan .

  5. Kami tidak perlu membuat perubahan apa pun pada tindakan Berikutnya , jika Anda menyelesaikan kode tambahan untuk bagian sebelumnya tentang pemesanan berdasarkan beberapa properti.

Menjalankan dan menguji aplikasi

  1. Jalankan aplikasi. Anda akan melihat serangkaian fasilitas lengkap dalam tampilan.

  2. Untuk pemesanan, memilih "Berdasarkan Peringkat numerik" akan memberi Anda urutan numerik yang telah Anda terapkan dalam tutorial ini, dengan tanggal renovasi yang memutuskan di antara hotel dengan peringkat yang sama.

    Memesan

  3. Sekarang coba profil "Berdasarkan fasilitas". Buat berbagai pilihan fasilitas, dan verifikasi bahwa hotel dengan fasilitas tersebut dipromosikan ke daftar hasil.

    Memesan

  4. Coba "Berdasarkan Profil tanggal/Peringkat yang Direnovasi" untuk melihat apakah Anda mendapatkan apa yang Anda harapkan. Hanya hotel yang baru saja direnovasi yang harus mendapatkan peningkatan kesegaran .

Sumber Daya

Untuk informasi selengkapnya, lihat Menambahkan profil penilaian berikut ini ke indeks Azure Cognitive Search.

Kesimpulan

Pertimbangkan hal-hal berikut dari proyek ini:

  • Pengguna akan mengharapkan hasil pencarian diurutkan, paling relevan terlebih dahulu.
  • Kebutuhan data terstruktur sehingga pemesanan mudah. Kami tidak dapat mengurutkan "termurah" terlebih dahulu dengan mudah, karena data tidak terstruktur untuk memungkinkan pemesanan dilakukan tanpa kode tambahan.
  • Mungkin ada banyak tingkatan untuk memesan, untuk membedakan antara hasil yang memiliki nilai yang sama pada tingkat pemesanan yang lebih tinggi.
  • Adalah wajar untuk beberapa hasil untuk diurutkan dalam urutan naik (katakanlah, jarak jauh dari titik), dan beberapa dalam urutan menurun (katakanlah, peringkat tamu).
  • Profil penilaian dapat ditentukan ketika perbandingan numerik tidak tersedia, atau tidak cukup canggih, untuk himpunan data. Menilai setiap hasil akan membantu mengurutkan dan menampilkan hasilnya dengan cerdas.

Langkah selanjutnya

Anda telah menyelesaikan serangkaian tutorial C# ini - Anda seharusnya mendapatkan pengetahuan berharga tentang API Azure Cognitive Search.

Untuk referensi dan tutorial lebih lanjut, pertimbangkan untuk menelusuri katalog pelatihan Microsoft Learn atau tutorial lain dalam dokumentasi Azure Cognitive Search.