Oktatóanyag: Keresési eredmények megrendelése a .NET SDK használatával

Ebben az oktatóanyag-sorozatban az eredmények alapértelmezett sorrendben lettek visszaadva és megjelenítve. Ebben az oktatóanyagban elsődleges és másodlagos rendezési szempontokat fog hozzáadni. A numerikus értékek alapján történő rendezés alternatívaként az utolsó példa bemutatja, hogyan rangsorolhatja az eredményeket egy egyéni pontozási profil alapján. Egy kicsit részletesebben is megismerkedünk az összetett típusok megjelenítésével.

Ebben az oktatóanyagban a következőket sajátíthatja el:

  • Találatok rendezése egy tulajdonság alapján
  • Találatok sorrendje több tulajdonság alapján
  • Eredmények rendezése pontozási profil szerint

Áttekintés

Ez az oktatóanyag kibővíti a Lapozás hozzáadása a keresési eredményekhez oktatóanyagban létrehozott végtelen görgetési projektet.

Az oktatóanyagban szereplő kód egy kész verziója a következő projektben található:

Előfeltételek

Eredmények rendezése egy tulajdonság alapján

Ha egy tulajdonság, például a szállodai minősítés alapján rendezzük az eredményeket, nem csak a sorrendezett eredményeket szeretnénk látni, hanem azt is szeretnénk, hogy megerősítést kapjunk arról, hogy a sorrend helyes. Ha hozzáadja az Értékelés mezőt az eredményekhez, meggyőződhet arról, hogy az eredmények megfelelően vannak rendezve.

Ebben a gyakorlatban egy kicsit többet is hozzáadunk az eredmények megjelenítéséhez: a legolcsóbb szobaár és a legdrágább szobaár minden szállodához.

A rendelés engedélyezéséhez nincs szükség a modellek módosítására. Csak a nézet és a vezérlő igényel frissítéseket. Először nyissa meg az otthoni vezérlőt.

Adja hozzá az OrderBy tulajdonságot a keresési paraméterekhez

  1. A HomeController.cs adja hozzá az OrderBy beállítást, és adja hozzá az Értékelés tulajdonságot csökkenő rendezési sorrendtel. Az Index(SearchData modell) metódusban adja hozzá a következő sort a keresési paraméterekhez.

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

    Megjegyzés:

    Az alapértelmezett sorrend növekvő, de asc hozzáadhatja a tulajdonsághoz, hogy egyértelmű legyen. Csökkenő sorrendet ad meg a hozzáadással desc.

  2. Most futtassa az alkalmazást, és adja meg a gyakori keresési kifejezéseket. Előfordulhat, hogy az eredmények nem a megfelelő sorrendben vannak, mivel sem Ön, sem a fejlesztő, sem a felhasználó nem tudja könnyen ellenőrizni az eredményeket!

  3. Tisztázzuk, hogy az eredmények az értékelés alapján vannak rendezve. Először cserélje le a hotels.css fájl box1 és box2 osztályát a következő osztályokra (ezek az osztályok az oktatóanyaghoz szükséges új osztályok).

    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;
    }
    

    Jótanács

    A böngészők általában gyorsítótárazzák a css-fájlokat, és ez egy régi css-fájl használatát eredményezheti, és a módosítások figyelmen kívül hagyhatók. Ennek jó módja, ha egy verzióparaméterrel rendelkező lekérdezési sztringet ad hozzá a hivatkozáshoz. Például:

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

    Frissítse a verziószámot, ha úgy gondolja, hogy a böngésző egy régi CSS-fájlt használ.

  4. Adja hozzá a Minősítés tulajdonságot a Select paraméterhez az Index(SearchData modell) metódusban, hogy az eredmények a következő három mezőt tartalmazzák:

    options.Select.Add("HotelName");
    options.Select.Add("Description");
    options.Select.Add("Rating");
    
  5. Nyissa meg a nézetet (index.cshtml), és cserélje le a renderelési ciklust (<-- A szálloda adatainak megjelenítése. -->) a következő kódra.

    <!-- 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. A minősítésnek elérhetőnek kell lennie mind az első megjelenített oldalon, mind a végtelen görgetéssel elérhető későbbi oldalakon. A két helyzet közül az utóbbi esetében frissíteni kell a vezérlő Következő műveletét és a nézetben található görgetett függvényt is. A vezérlőtől kezdve módosítsa a Következő metódust a következő kódra. Ez a kód létrehozza és közli a minősítés szövegét.

    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. Most frissítse a nézetben a görgetett függvényt a minősítés szövegének megjelenítéséhez.

    <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. Most futtassa újra az alkalmazást. Keressen rá bármilyen általános kifejezésre, például a "wifi"-ra, és ellenőrizze, hogy a találatok a szállodai minősítés csökkenő sorrendjében vannak-e rendezve.

    Rendelés minősítés alapján

    Megfigyelheti, hogy több szálloda azonos minősítéssel rendelkezik, így a megjelenítésben való megjelenésük ismét az adatok keresésének sorrendje, ami tetszőleges.

    Mielőtt egy második szintű megrendelést adnánk hozzá, adjunk hozzá néhány kódot a szobaárak tartományának megjelenítéséhez. Ezt a kódot hozzáadjuk ahhoz, hogy az adatok összetett típusból történő kinyerését is megjelenítsük, és hogy az ár alapján is meg tudjuk vitatni a rendelési eredményeket (talán a legolcsóbb először).

A szobaárak tartományának hozzáadása a nézethez

  1. Adja hozzá a szobák legolcsóbb és legdrágább árait tartalmazó tulajdonságokat a Hotel.cs modellhez.

    // Room rate range
    public double cheapest { get; set; }
    public double expensive { get; set; }
    
  2. Számítsa ki a szobaárakat az Index(SearchData modell) művelet végén, az otthoni vezérlőben. Adja hozzá a számításokat az ideiglenes adatok tárolása után.

    // 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. Adja hozzá a Szobák tulajdonságot a vezérlő Index(SearchData modell) műveletének Select paraméteréhez.

    options.Select.Add("Rooms");
    
  4. Módosítsa a megjelenítési ciklust a nézetben az eredmények első oldalának sebességtartományának megjelenítéséhez.

    <!-- 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. Módosítsa a Következő metódust a kezdővezérlőben a sebességtartomány közléséhez a későbbi találati lapok esetében.

    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. Frissítse a nézetben a görgetett függvényt a szobadíj szövegének kezeléséhez.

    <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. Futtassa az alkalmazást, és ellenőrizze, hogy megjelennek-e a szobadíjtartományok.

    Helyiségár-tartományok megjelenítése

A keresési paraméterek OrderBy tulajdonsága nem fogad el olyan bejegyzést, mint például a Rooms.BaseRate , amely a legolcsóbb szobaárat biztosítja, még akkor sem, ha a szobák már a díjszabás szerint lettek rendezve. Ebben az esetben a szobák nincsenek díjszabás szerint rendezve. Ahhoz, hogy a szállodák a mintaadatkészletben jelenjenek meg, a szobaár szerint rendezve, az eredményeket az otthoni vezérlőben kell rendezni, és ezeket az eredményeket a kívánt sorrendben kell elküldeni a nézetre.

Eredmények sorrendje több érték alapján

A kérdés most az, hogyan lehet megkülönböztetni az azonos minősítésű szállodákat. Az egyik megközelítés lehet egy másodlagos rendezés az utolsó felújítás időpontja alapján, így a közelmúltban felújított szállodák magasabban jelennek meg az eredményekben.

  1. A második szintű rendezés hozzáadásához adja hozzá a LastRenovationDate értéket a keresési eredményekhez és az OrderBy-hez az Index(SearchData modell) metódusban.

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

    Jótanács

    Tetszőleges számú tulajdonság beírható az OrderBy listába. Ha a hotelek azonos minősítési és felújítási dátummal rendelkeznek, egy harmadik ingatlant is be lehetne írni, hogy különbséget tegyen közöttük.

  2. Ismét meg kell látnunk a felújítás dátumát a nézetben, csak hogy biztos lehessen abban, hogy a megrendelés helyes. Egy ilyen dolog, mint a felújítás, valószínűleg csak az év elegendő. Módosítsa a megjelenítési ciklust a nézetben a következő kódra.

    <!-- 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. Módosítsa a Next metódust az otthoni vezérlőben az utolsó felújítási dátum év összetevőjének továbbításához.

        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. Módosítsa a nézetben a görgetett függvényt a felújítási szöveg megjelenítéséhez.

    <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. Nyisd meg az alkalmazást. Keressen rá egy közös kifejezésre, például a "pool" vagy a "view" kifejezésre, és ellenőrizze, hogy az azonos minősítéssel rendelkező szállodák mostantól csökkenő sorrendben jelennek-e meg a felújítás dátumától függően.

    Megrendelés a felújítás napján

Eredmények sorrendezése pontozási profil alapján

Az oktatóanyag eddigi példái bemutatják, hogyan lehet számértékeket (minősítési és felújítási dátumot) sorrendbe rendezni, pontos sorrendet biztosítva . Egyes keresések és adatok azonban nem teszik lehetővé a két adatelem ilyen egyszerű összehasonlítását. A teljes szöveges keresési lekérdezésekhez a Cognitive Search tartalmazza a rangsorolás fogalmát. A pontozási profilok megadhatók az eredmények rangsorolásának befolyásolása érdekében, így összetettebb és minőségibb összehasonlításokat végezhetnek.

A pontozási profilok az indexsémában vannak definiálva. Több pontozási profil is be lett állítva a hoteladatokon. Nézzük meg, hogyan van definiálva egy pontozási profil, majd próbáljon meg kódot írni a kereséshez.

Pontozási profilok definiálása

A pontozási profilok a tervezéskor egy keresési indexben vannak definiálva. A Microsoftnál üzemeltetett csak olvasható szállodai index három pontozási profillal rendelkezik. Ez a szakasz a pontozási profilokat mutatja be, és megmutatja, hogyan használja azokat a kódban.

  1. Az alábbiakban látható a szállodai adatkészlet alapértelmezett pontozási profilja, amely akkor használatos, ha nem ad meg OrderBy vagy ScoringProfile paramétert. Ez a profil növeli a szálloda pontszámát akkor, ha a keresési szöveg szerepel a szálloda nevében, leírásában vagy címkéinek listájában (kényelmi szolgáltatások). Figyelje meg, hogy a pontozás súlyozása hogyan kedvez bizonyos mezőknek. Ha a keresési szöveg egy másik mezőben jelenik meg, és nem szerepel az alábbiakban, akkor az 1 súlyú lesz. Nyilvánvaló, hogy minél magasabb a pontszám, annál előkelőbb helyet foglal el az eredmény a nézetben.

    {
       "name": "boostByField",
       "text": {
           "weights": {
               "Tags": 3,
               "HotelName": 2,
               "Description": 1.5,
               "Description_fr": 1.5,
           }
       }
    }
    
  2. Az alábbi alternatív pontozási profil jelentősen növeli a pontszámot, ha egy megadott paraméter tartalmaz egy vagy több címkét (amelyeket "kényelemnek" hívunk). Ennek a profilnak a legfontosabb pontja, hogy meg kell adni egy paramétert, amely szöveget tartalmaz. Ha a paraméter üres vagy nincs megadva, hibaüzenet jelenik meg.

    {
        "name":"boostAmenities",
        "functions":[
            {
            "fieldName":"Tags",
            "freshness":null,
            "interpolation":"linear",
            "magnitude":null,
            "distance":null,
            "tag":{
                "tagsParameter":"amenities"
            },
            "type":"tag",
            "boost":5
            }
        ],
        "functionAggregation":0
    },
    
  3. Ebben a harmadik profilban a szálloda értékelése jelentős lökést ad a pontszámnak. Az utolsó felújított dátum szintén növeli a pontszámot, de csak akkor, ha az adatok az aktuális dátumtól számított 730 napon (2 éven) belülre esnek.

    {
        "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
    }
    

    Most nézzük meg, hogy ezek a profilok úgy működnek-e, ahogy gondoljuk.

Kód hozzáadása a nézethez a profilok összehasonlításához

  1. Nyissa meg az index.cshtml fájlt, és cserélje le a <törzsszakaszt> a következő kódra.

    <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. Nyissa meg a SearchData.cs fájlt, és cserélje le a SearchData osztályt a következő kódra.

    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. Nyissa meg a hotels.css fájlt, és adja hozzá a következő HTML-osztályokat.

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

Kód hozzáadása a vezérlőhöz pontozási profil megadásához

  1. Nyissa meg az otthoni vezérlőfájlt. Adja hozzá a következő using utasítást (listák létrehozásához).

    using System.Linq;
    
  2. Ebben a példában az Index kezdeti hívására van szükség, hogy egy kicsit többet tegyünk, mint a kezdeti nézet visszaadása. A metódus mostantól legfeljebb 20 kényelmi szolgáltatást keres a nézetben való megjelenítéshez.

        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. Két privát módszerre van szükségünk, hogy az aspektusokat ideiglenes tárolóba mentsük, és helyreállítsuk őket az ideiglenes tárolóból, és feltöltsünk egy modellt.

        // 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. Szükség szerint be kell állítani az OrderBy és a ScoringProfile paramétereket. Cserélje le a meglévő Index(SearchData-modell) metódust a következőre.

    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);
    }
    

    Olvassa el az egyes kapcsolóválasztások megjegyzéseit.

  5. Nem kell módosítanunk a Következő műveletet, ha az előző szakaszhoz tartozó további kódot több tulajdonság alapján rendelte el.

Az alkalmazás futtatása és tesztelése

  1. Nyisd meg az alkalmazást. A látványban a kényelmi lehetőségek teljes készletének láthatóak kellene lenniük.

  2. A rendezéshez válassza a "Numerikus minősítéssel" lehetőséget, hogy alkalmazza az oktatóanyagban már implementált numerikus sorrendet; a felújítás dátuma dönti el, melyik szállodát válasszuk az egyenlő minősítésűek közül.

  3. Most próbálja ki a „Szolgáltatások szerint” profilt. Válasszon különféle kényelmi lehetőségeket, és ellenőrizze, hogy az ilyen kényelmi funkciókkal rendelkező szállodák felkerülnek-e az eredmények listájára.

    A

  4. Próbálja ki a "Felújított dátum/minősítési profil szerint" elemet, és ellenőrizze, hogy megkapja-e, amit vár. Csak a közelmúltban felújított szállodák kapjanak frissességet növelő lendületet.

Erőforrások

További információ: Pontozási profilok hozzáadása egy Azure Cognitive Search-indexhez.

Főbb tanulságok

Vegye figyelembe a projekt alábbi tanulságait:

  • A felhasználók azt várják, hogy a keresési eredmények sorrendben legyenek rendezve, először a legrelevánsabbak.
  • Az adatoknak strukturáltnak kell lennie, hogy a rendezés egyszerű legyen. Nem tudtuk könnyen a "legolcsóbb" szerint rendezni, mivel az adatok nem olyan módon vannak strukturálva, hogy további kód nélkül lehessen sorrendet állítani.
  • A rendezésnek számos szintje lehet, hogy különbséget lehessen tenni az azonos értékkel rendelkező eredmények között a magasabb sorrendben.
  • Természetes, hogy egyes eredményeket növekvő sorrendben kell rendezni (például egy ponttól való távolság), és néhányat csökkenő sorrendben (például a vendég értékelése).
  • Pontozási profilok akkor határozhatók meg, ha a numerikus összehasonlítások nem érhetők el, vagy nem elég intelligensek egy adathalmazhoz. Az egyes eredmények pontozása segít az eredmények intelligens sorrendjében és megjelenítésében.

Következő lépések

Elvégezte ezt a C#-oktatóanyag-sorozatot – értékes ismeretekkel kellett volna rendelkeznie az Azure Cognitive Search API-król.

További információkért és oktatóanyagokért tekintse meg a Microsoft Learn képzési katalógusát vagy az Azure Cognitive Search dokumentációjában található egyéb oktatóanyagokat.