Frissítés az Azure Search .NET SDK 1.1-es verziójára

Ha az Azure Search .NET SDK 1.0.2-es vagy újabb verzióját használja, ez a cikk segít frissíteni az alkalmazást az 1.1-es verzió használatára.

Az SDK általánosabb, példákat is tartalmazó bemutatása: Az Azure Search használata .NET-alkalmazásból.

Megjegyzés:

Miután frissített az 1.1-es verzióra, vagy ha már 1.1 és 2.0 közötti verziót használ, frissítsen a 3. verzióra. Útmutatásért tekintse meg Frissítés az Azure Search .NET SDK 3- verziójára.

Először is frissítse a Microsoft.Azure.Search NuGet hivatkozást a NuGet csomagkezelő konzol használatával, vagy kattintson a jobb gombbal a projekt hivatkozásaira, és válassza a "NuGet-csomagok kezelése..." lehetőséget a Visual Studio-ban.

Miután a NuGet letöltötte az új csomagokat és azok függőségeit, építse újra a projektet.

Ha korábban az 1.0.0-s, 1.0.1-es vagy 1.0.2-es előzetes verziót használta, a buildnek sikeresnek kell lennie, és készen áll a használatra!

Ha korábban a 0.13.0-s vagy régebbi verziót használta, az alábbihoz hasonló buildelési hibákat kell látnia:

Program.cs(137,56,137,62): error CS0117: 'Microsoft.Azure.Search.Models.IndexBatch' does not contain a definition for 'Create'
Program.cs(137,99,137,105): error CS0117: 'Microsoft.Azure.Search.Models.IndexAction' does not contain a definition for 'Create'
Program.cs(146,41,146,54): error CS1061: 'Microsoft.Azure.Search.IndexBatchException' does not contain a definition for 'IndexResponse' and no extension method 'IndexResponse' accepting a first argument of type 'Microsoft.Azure.Search.IndexBatchException' could be found (are you missing a using directive or an assembly reference?)
Program.cs(163,13,163,42): error CS0246: The type or namespace name 'DocumentSearchResponse' could not be found (are you missing a using directive or an assembly reference?)

A következő lépés a buildelési hibák egyenkénti kijavítása. A legtöbb esetben módosítania kell az SDK-ban átnevezett osztály- és metódusneveket. Az 1.1-es verzió kompatibilitástörő változásainak listája tartalmazza a névmódosítások listáját.

Ha egyéni osztályokat használ a dokumentumok modellezéséhez, és ezek az osztályok nem null értékű primitív típusú (például int vagy bool) tulajdonságokkal rendelkeznek, ügyeljen rá, hogy az SDK 1.1-es verziójában hibajavítás történt, amiről tudnia kell. További részletekért tekintse meg az 1.1-es verzió hibajavítását .

Végül, miután kijavított minden buildelési hibát, módosíthatja az alkalmazást, hogy igény szerint kihasználhassa az új funkciókat.

Az 1.1-es verzió kompatibilitástörő változásainak listája

Az alábbi listát annak valószínűsége rendezi, hogy a módosítás hatással lesz az alkalmazás kódra.

Az IndexBatch és az IndexAction változásai

IndexBatch.Create nevét IndexBatch.New ért módosították, és params argumentum már nem található meg. Különböző típusú műveleteket (egyesítéseket, törléseket stb.) tartalmazó kötegekhez használható IndexBatch.New . Emellett új statikus metódusok is léteznek a kötegek létrehozásához, ahol az összes művelet megegyezik: Delete, Merge, MergeOrUploadés Upload.

IndexAction már nem rendelkeznek nyilvános konstruktorokkal, és tulajdonságai már nem módosíthatók. Az új statikus metódusokkal különböző célokra hozhat létre műveleteket: Delete, Merge, MergeOrUploadés Upload. IndexAction.Create el lett távolítva. Ha olyan túlterhelést használt, amely csak egy dokumentumot vesz igénybe, mindenképpen használja Upload helyette.

példa

Ha a kód így néz ki:

var batch = IndexBatch.Create(documents.Select(doc => IndexAction.Create(doc)));
indexClient.Documents.Index(batch);

A buildelési hibák kijavításához módosítsa a következőre:

var batch = IndexBatch.New(documents.Select(doc => IndexAction.Upload(doc)));
indexClient.Documents.Index(batch);

Ha szeretné, a következő módon egyszerűsítheti tovább:

var batch = IndexBatch.Upload(documents);
indexClient.Documents.Index(batch);

IndexBatchException változások

A IndexBatchException.IndexResponse tulajdonság át lett nevezve IndexingResults-re, és most már a típusa IList<IndexingResult>.

példa

Ha a kód így néz ki:

catch (IndexBatchException e)
{
    Console.WriteLine(
        "Failed to index some of the documents: {0}",
        String.Join(", ", e.IndexResponse.Results.Where(r => !r.Succeeded).Select(r => r.Key)));
}

A buildelési hibák kijavításához módosítsa a következőre:

catch (IndexBatchException e)
{
    Console.WriteLine(
        "Failed to index some of the documents: {0}",
        String.Join(", ", e.IndexingResults.Where(r => !r.Succeeded).Select(r => r.Key)));
}

Műveletmetódus módosítása

Az Azure Search .NET SDK minden művelete a szinkron és aszinkron hívók metódusterheléseinek készleteként jelenik meg. A metódus túlterheléseinek aláírása és faktorálása az 1.1-es verzióban megváltozott.

Az SDK régebbi verzióiban az "Indexstatisztika lekérése" művelet például a következő aláírásokat tette közzé:

In IIndexOperations:

// Asynchronous operation with all parameters
Task<IndexGetStatisticsResponse> GetStatisticsAsync(
    string indexName,
    CancellationToken cancellationToken);

A IndexOperationsExtensions:

// Asynchronous operation with only required parameters
public static Task<IndexGetStatisticsResponse> GetStatisticsAsync(
    this IIndexOperations operations,
    string indexName);

// Synchronous operation with only required parameters
public static IndexGetStatisticsResponse GetStatistics(
    this IIndexOperations operations,
    string indexName);

Az 1.1-es verzióban ugyanahhoz a művelethez tartozó metódus-aláírások a következőképpen néznek ki:

A IIndexesOperations:

// Asynchronous operation with lower-level HTTP features exposed
Task<AzureOperationResponse<IndexGetStatisticsResult>> GetStatisticsWithHttpMessagesAsync(
    string indexName,
    SearchRequestOptions searchRequestOptions = default(SearchRequestOptions),
    Dictionary<string, List<string>> customHeaders = null,
    CancellationToken cancellationToken = default(CancellationToken));

A IndexesOperationsExtensions:

// Simplified asynchronous operation
public static Task<IndexGetStatisticsResult> GetStatisticsAsync(
    this IIndexesOperations operations,
    string indexName,
    SearchRequestOptions searchRequestOptions = default(SearchRequestOptions),
    CancellationToken cancellationToken = default(CancellationToken));

// Simplified synchronous operation
public static IndexGetStatisticsResult GetStatistics(
    this IIndexesOperations operations,
    string indexName,
    SearchRequestOptions searchRequestOptions = default(SearchRequestOptions));

Az 1.1-es verziótól kezdve az Azure Search .NET SDK eltérően rendszerezi a műveleti módszereket:

  • Az opcionális paraméterek mostantól alapértelmezett paraméterekként vannak modellve a további metódusterhelések helyett. Ez csökkenti a metódusok túlterheléseinek számát, néha drámai módon.
  • A bővítménymetelyek mostantól elrejtik a HTTP sok felesleges részletét a hívó elől. Az SDK régebbi verziói például egy HTTP-állapotkóddal rendelkező válaszobjektumot adtak vissza, amelyet gyakran nem kellett ellenőriznie, mert a műveleti módszerek hibát jelző állapotkódot adnak CloudException vissza. Az új bővítménymetódusok csak modellobjektumokat adnak vissza, így nem kell a kódban kicsomagolni őket.
  • Ezzel szemben az alapvető interfészek mostantól olyan módszereket is elérhetővé tesz, amelyek nagyobb ellenőrzést biztosítanak a HTTP-szinten, ha szükség van rá. Most már átadhat egyéni HTTP-fejléceket, hogy szerepeljenek a kérelmekben, és az új AzureOperationResponse<T> visszatérési típus közvetlen hozzáférést biztosít a HttpRequestMessage és HttpResponseMessage elemekhez a művelet során. AzureOperationResponse a Microsoft.Rest.Azure névtérben van definiálva, és lecseréli Hyak.Common.OperationResponse.

A ScoringParameters változásai

A legújabb SDK-ban új osztály lett hozzáadva ScoringParameter , amely megkönnyíti a keresési lekérdezések pontozási profiljainak paramétereinek megadását. Korábban az ScoringProfiles osztály tulajdonsága a SearchParameters típusa IList<string> volt; most a típusa IList<ScoringParameter>.

példa

Ha a kód így néz ki:

var sp = new SearchParameters();
sp.ScoringProfile = "jobsScoringFeatured";      // Use a scoring profile
sp.ScoringParameters = new[] { "featuredParam-featured", "mapCenterParam-" + lon + "," + lat };

A buildelési hibák kijavításához módosítsa a következőre:

var sp = new SearchParameters();
sp.ScoringProfile = "jobsScoringFeatured";      // Use a scoring profile
sp.ScoringParameters =
    new[]
    {
        new ScoringParameter("featuredParam", new[] { "featured" }),
        new ScoringParameter("mapCenterParam", GeographyPoint.Create(lat, lon))
    };

Modellosztály változásai

A műveletmetódusban leírt aláírásváltozások miatt a Microsoft.Azure.Search.Models névtér számos osztályát átnevezték vagy eltávolították. Például:

  • IndexDefinitionResponse helyébe AzureOperationResponse<Index> került
  • A DocumentSearchResponse új nevet kapott: DocumentSearchResult
  • A IndexResult új nevet kapott: IndexingResult
  • Documents.Count() most egy dokumentumszámmal rendelkező értéket ad long vissza ahelyett, hogy DocumentCountResponse
  • A IndexGetStatisticsResponse új nevet kapott: IndexGetStatisticsResult
  • A IndexListResponse új nevet kapott: IndexListResult

Összefoglalva, OperationResponsea csak modellobjektum becsomagolására létező származtatott osztályok el lettek távolítva. A maradék osztályok utótagja megváltozott Response-ról Result-re.

példa

Ha a kód így néz ki:

IndexerGetStatusResponse statusResponse = null;

try
{
    statusResponse = _searchClient.Indexers.GetStatus(indexer.Name);
}
catch (Exception ex)
{
    Console.WriteLine("Error polling for indexer status: {0}", ex.Message);
    return;
}

IndexerExecutionResult lastResult = statusResponse.ExecutionInfo.LastResult;

A buildelési hibák kijavításához módosítsa a következőre:

IndexerExecutionInfo status = null;

try
{
    status = _searchClient.Indexers.GetStatus(indexer.Name);
}
catch (Exception ex)
{
    Console.WriteLine("Error polling for indexer status: {0}", ex.Message);
    return;
}

IndexerExecutionResult lastResult = status.LastResult;

Választípusok és IEnumerable

A kódra további hatással lehet, hogy a gyűjteményeket tartalmazó válaszosztályok már nem implementálhatók IEnumerable<T>. Ehelyett közvetlenül is elérheti a gyűjteménytulajdonságot. Ha például a kód így néz ki:

DocumentSearchResponse<Hotel> response = indexClient.Documents.Search<Hotel>(searchText, sp);
foreach (SearchResult<Hotel> result in response)
{
    Console.WriteLine(result.Document);
}

A buildelési hibák kijavításához módosítsa a következőre:

DocumentSearchResult<Hotel> response = indexClient.Documents.Search<Hotel>(searchText, sp);
foreach (SearchResult<Hotel> result in response.Results)
{
    Console.WriteLine(result.Document);
}

Speciális eset webalkalmazásokhoz

Ha olyan webalkalmazással rendelkezik, amely közvetlenül szerializálja DocumentSearchResponse a keresési eredményeket a böngészőbe, módosítania kell a kódot, vagy az eredmények nem lesznek megfelelően szerializálva. Ha például a kód így néz ki:

public ActionResult Search(string q = "")
{
    // If blank search, assume they want to search everything
    if (string.IsNullOrWhiteSpace(q))
        q = "*";

    return new JsonResult
    {
        JsonRequestBehavior = JsonRequestBehavior.AllowGet,
        Data = _featuresSearch.Search(q)
    };
}

A keresési válasz tulajdonságának lekérésével .Results módosíthatja a találatok megjelenítésének javításához:

public ActionResult Search(string q = "")
{
    // If blank search, assume they want to search everything
    if (string.IsNullOrWhiteSpace(q))
        q = "*";

    return new JsonResult
    {
        JsonRequestBehavior = JsonRequestBehavior.AllowGet,
        Data = _featuresSearch.Search(q).Results
    };
}

Az ilyen eseteket saját magának kell keresnie a kódban; a fordító nem fogja figyelmeztetni, mert JsonResult.Data egy object típus.

CloudException-módosítások

Az CloudException osztály áthelyeződött a Hyak.Common névtérből a Microsoft.Rest.Azure névtérbe. Ezenkívül a Error tulajdonságát átnevezték Body-re.

A SearchServiceClient és a SearchIndexClient változásai

A Credentials tulajdonság típusa megváltozott SearchCredentials-ról az alaposztályára, ServiceClientCredentials-re. Ha hozzá kell férnie a SearchCredentials, a SearchIndexClient vagy a SearchServiceClient, használja az új SearchCredentials tulajdonságot.

Az SDK régebbi verzióiban a SearchServiceClient és SearchIndexClient rendelkezett olyan konstruktorokkal, amelyek HttpClient paraméterként fogadták. Ezeket olyan konstruktorokra cserélték, amelyek egy HttpClientHandler és több objektumból álló DelegatingHandler tömböt vesznek fel. Ez megkönnyíti az egyéni kezelők telepítését a HTTP-kérések előzetes feldolgozásához, ha szükséges.

Végül, megváltoztak azok a konstruktorok, amelyek egy Uri és egy SearchCredentials-et vettek fel. Ha például a következőhöz hasonló kóddal rendelkezik:

var client =
    new SearchServiceClient(
        new SearchCredentials("abc123"),
        new Uri("http://myservice.search.windows.net"));

A buildelési hibák kijavításához módosítsa a következőre:

var client =
    new SearchServiceClient(
        new Uri("http://myservice.search.windows.net"),
        new SearchCredentials("abc123"));

Azt is vegye figyelembe, hogy a hitelesítő adatok paraméter ServiceClientCredentialstípusa megváltozott. Ez valószínűleg nem befolyásolja a kódodat, mivel a SearchCredentials a ServiceClientCredentials-ből származik.

Kérelemazonosító átadása

Az SDK régebbi verzióiban beállíthatott egy kérésazonosítót a SearchServiceClient vagy SearchIndexClient elemeken, és az minden kérésben szerepelt volna a REST API-hoz. Ez hasznos a keresési szolgáltatással kapcsolatos problémák elhárításához, ha kapcsolatba kell lépnie az ügyfélszolgálattal. Hasznosabb azonban minden művelethez egyedi kérésazonosítót beállítani, nem pedig ugyanazt az azonosítót használni az összes művelethez. Ezért a SetClientRequestId metódusok SearchServiceClientSearchIndexClient el lettek távolítva. Ehelyett az opcionális SearchRequestOptions paraméteren keresztül minden műveletmetódusnak átadhat egy kérelemazonosítót.

Megjegyzés:

Az SDK egy későbbi kiadásában egy új mechanizmust fogunk hozzáadni a kérésazonosító globális beállításához az ügyfélobjektumokon, amely összhangban van a többi Azure SDK által alkalmazott megközelítéssel.

példa

Ha a következőhöz hasonló kóddal rendelkezik:

client.SetClientRequestId(Guid.NewGuid());
...
long count = client.Documents.Count();

A buildelési hibák kijavításához módosítsa a következőre:

long count = client.Documents.Count(new SearchRequestOptions(requestId: Guid.NewGuid()));

A felület nevének módosítása

A műveleti csoport felületének nevei mind módosultak, hogy összhangban legyenek a megfelelő tulajdonságnevekkel:

  • A(z) ISearchServiceClient.Indexes típust átnevezték erről: IIndexOperations erre: IIndexesOperations.
  • A(z) ISearchServiceClient.Indexers típust átnevezték IIndexerOperations-ról/-ről IIndexersOperations-ra/-re.
  • A ISearchServiceClient.DataSources típust átnevezték IDataSourceOperations-ról IDataSourcesOperations-ra.
  • A(z) ISearchIndexClient.Documents típus nevét IDocumentOperations-ről IDocumentsOperations-re változtatták.

Ez a módosítás valószínűleg nem befolyásolja a kódot, hacsak nem hozott létre próbaillesztéseket ezekről a felületekről tesztelés céljából.

Hibajavítások az 1.1-es verzióban

Hiba történt az Azure Search .NET SDK régebbi verzióiban az egyéni modellosztályok szerializálásával kapcsolatban. A hiba akkor fordulhat elő, ha nem null értékű tulajdonságú egyéni modellosztályt hozott létre.

A reprodukálás lépései

Hozzon létre egy egyéni modellosztályt nem null értékű tulajdonsággal. Például adjon hozzá egy nyilvános UnitCount típusú tulajdonságot int ahelyett int?, hogy .

Ha egy ilyen típusú (például 0 int) alapértelmezett értékkel rendelkező dokumentumot indexel, a mező null értékű lesz az Azure Searchben. Ha később megkeresi a dokumentumot, a Search hívás arra panaszkodni fog, hogy nem lehet null átkonvertálni int-ba.

Emellett előfordulhat, hogy a szűrők nem a várt módon működnek, mivel a null érték a kívánt érték helyett az indexbe lett írva.

Részletek javítása

Ezt a problémát az SDK 1.1-es verziójában javítottuk. Most, ha van egy ilyen típusú modell osztálya:

public class Model
{
    public string Key { get; set; }

    public int IntValue { get; set; }
}

és 0 értékre állítja IntValue , ez az érték most már helyesen szerializálva van 0-ként a vezetéken, és 0-ként van tárolva az indexben. Az oda-vissza működés a várt módon is működik.

Ezzel a megközelítéssel egy lehetséges probléma merülhet fel: Ha nem null értékű tulajdonsággal rendelkező modelltípust használ, akkor garantálnia kell, hogy az index egyik dokumentuma sem tartalmaz null értéket a megfelelő mezőhöz. Sem az SDK, sem az Azure Search REST API nem segít a kényszerítésben.

Ez nem csupán hipotetikus probléma: Képzeljen el egy olyan forgatókönyvet, amelyben új mezőt ad hozzá egy meglévő, típusú Edm.Int32indexhez. Az indexdefiníció frissítése után minden dokumentum null értékű lesz az új mezőhöz (mivel az Azure Searchben minden típus null értékű). Ha ezután egy modellosztályt használ a mező nem null értékű int tulajdonságával, a dokumentumok lekérésekor a következőhöz hasonlót fog kapni JsonSerializationException :

Error converting value {null} to type 'System.Int32'. Path 'IntValue'.

Ezért továbbra is javasoljuk, hogy ajánlott eljárásként null értékű típusokat használjon a modellosztályokban.

A hibával és a javítással kapcsolatos további részletekért tekintse meg ezt a problémát a GitHubon.