Bagikan melalui


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 memesan berdasarkan nilai numerik, contoh akhir menunjukkan cara memberi peringkat hasil berdasarkan profil penilaian kustom. Kami juga akan sedikit mendalami tampilan jenis kompleks.

Dalam tutorial ini, Anda akan mempelajari cara:

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

Gambaran Umum

Tutorial ini memperluas proyek pengguliran tanpa batas yang dibuat di tutorial Menambahkan penomoran ke hasil pencarian.

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

Prasyarat

Mengurutkan hasil berdasarkan satu properti

Ketika 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 hasilnya diurutkan dengan benar.

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

Anda tidak perlu mengubah model apa pun untuk memungkinkan 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 sortir menurun. Dalam metode Index(model SearchData) , tambahkan baris berikut ke parameter pencarian.

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

    Catatan

    Urutan defaultnya adalah naik, meskipun Anda dapat menambahkan asc ke properti untuk memperjelas hal ini. Urutan menurun 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 bukan sebagai pengembang, bukan pengguna, memiliki cara mudah untuk memverifikasi hasilnya!

  3. Mari jelaskan hasilnya diurutkan berdasarkan peringkat. Pertama, ganti kelas box1 dan box2 di file hotel.css dengan kelas berikut (kelas ini adalah kelas baru yang dibutuhkan 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;
    }
    

    Tip

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

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

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

  4. Tambahkan properti Peringkat ke parameter Pilih, dalam metode Index(model SearchData) sehingga hasilnya mencakup 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 di halaman pertama yang ditampilkan, dan di halaman berikutnya yang dipanggil melalui pengguliran tanpa batas. Untuk yang terakhir dari dua situasi ini, kami perlu memperbarui tindakan Berikutnya di pengontrol, dan fungsi digulir dalam tampilan. Dimulai dengan pengontrol, ubah metode Berikutnya ke kode berikut. Kode ini membuat dan menyampaikan 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 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 menurun untuk peringkat hotel.

    Mengurutkan berdasarkan peringkat

    Anda akan melihat bahwa beberapa hotel memiliki peringkat yang identik, sehingga tampilannya di layar lagi merupakan urutan data ditemukan, yang bersifat arbitrer.

    Sebelum mambahas menambahkan tingkat kedua pengurutan, mari tambahkan beberapa kode untuk menampilkan rentang tarif kamar. Kami menambahkan kode ini untuk menunjukkan proses ekstrak data dari jenis kompleks, dan juga agar kami dapat mendiskusikan hasil pengurutan berdasarkan harga (mungkin dari yang termurah dulu).

Menambahkan 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(model SearchData) , di pengontrol rumah. Menambahkan 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 Index(model SearchData) pengontrol.

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

    <!-- 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 menyampaikan rentang tarif, 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 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 pastikan bahwa 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, meski kamar sudah diurutkan berdasarkan harga. 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, dan mengirim hasil ini ke tampilan dalam urutan yang diinginkan.

Mengurutkan hasil berdasarkan beberapa nilai

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

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

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

    Tip

    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, kami perlu melihat tanggal renovasi dalam tampilan, hanya untuk memastikan pengurutannya benar. Untuk hal seperti renovasi, mungkin hanya menampilkan tahun 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 digulir 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. Menjalankan aplikasi. Cari pada istilah umum, seperti "kumpulan" atau "tampilan", dan verifikasi bahwa hotel dengan peringkat yang sama sekarang ditampilkan dalam urutan menurun dari tanggal renovasi.

    Mengurutkan berdasarkan tanggal renovasi

Mengurutkan hasil berdasarkan profil penilaian

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

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

Bagaimana profil penilaian ditentukan

Profil penilaian didefinisikan dalam indeks pencarian pada waktu desain. Indeks hotel baca-saja yang dihosting oleh Microsoft memiliki tiga profil penilaian. Bagian ini menjelajahi profil penilaian dan menunjukkan cara menggunakan 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 dalam nama hotel, deskripsi, atau daftar tag (fasilitas). Perhatikan bagaimana bobot skor mendukung bidang tertentu. Jika teks pencarian muncul di bidang lain, tidak tercantum di bawah ini, teks tersebut akan memiliki bobot 1. Jelas saja, semakin tinggi skor, semakin tinggi hasil yang 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"). Poin penting dari profil ini adalah bahwa parameter harus disediakan, sehingga berisi teks. Jika parameter kosong, atau tidak disediakan, kesalahan akan ditampilkan.

    {
        "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 terhadap skor. Tanggal renovasi terakhir juga akan meningkatkan skor, tetapi hanya jika data tersebut jatuh dalam 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 lihat apakah profil ini berfungsi dengan semestinya.

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 pembuatan daftar).

    using System.Linq;
    
  2. Untuk contoh ini, kami perlu panggilan awal ke Indeks untuk melakukan 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. Kami membutuhkan dua metode pribadi untuk menyimpan faset ke penyimpanan sementara, serta 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. Kami perlu mengatur parameter OrderBy dan ScoringProfile seperlunya. Ganti metode Index(model SearchData) , yang ada dengan hal 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 beralih.

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

Jalankan dan uji aplikasi

  1. Menjalankan aplikasi. Anda akan melihat seperangkat fasilitas lengkap dalam tampilan.

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

    Mengurutkan

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

    Mengurutkan

  4. Coba "Berdasarkan Tanggal renovasi/Profil peringkat" untuk melihat apakah Anda mendapatkan apa yang Anda harapkan. Hanya hotel yang baru saja direnovasi yang akan mendapatkan peningkatan pembaruan.

Sumber

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

Kesimpulan

Pertimbangkan kesimpulan berikut dari proyek ini:

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

Langkah berikutnya

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

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