Upgrade na sadu .NET SDK služby Azure Search verze 1.1

Pokud používáte sadu .NET SDK služby Azure Search verze 1.0.2 nebo starší, pomůže vám tento článek upgradovat aplikaci tak, aby používala verzi 1.1.

Obecnější návod k sadě SDK včetně příkladů najdete v tématu Použití služby Azure Search z aplikace .NET.

Poznámka:

Po upgradu na verzi 1.1 nebo pokud už používáte verzi od 1.1 do 2.0-preview včetně, měli byste upgradovat na verzi 3. Pokyny najdete v tématu Upgrade na sadu .NET SDK služby Azure Search verze 3 .

Nejprve aktualizujte referenční informace NuGet pro Microsoft.Azure.Search pomocí konzoly Správce balíčků NuGet nebo kliknutím pravým tlačítkem myši na odkazy na projekt a výběrem možnosti Spravovat balíčky NuGet... v sadě Visual Studio.

Jakmile NuGet stáhne nové balíčky a jejich závislosti, znovu sestavte projekt.

Pokud jste dříve používali verzi 1.0.0-preview, 1.0.1-preview nebo 1.0.2-preview, měl by build proběhnout úspěšně a můžete začít!

Pokud jste dříve používali verzi 0.13.0-preview nebo starší, měli byste vidět chyby sestavení, jako je následující:

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?)

Dalším krokem je oprava chyb sestavení jednu po druhé. Většina bude vyžadovat změnu některých názvů tříd a metod, které byly přejmenovány v sadě SDK. Seznam zásadních změn ve verzi 1.1 obsahuje seznam těchto změn názvů.

Pokud k modelování dokumentů používáte vlastní třídy a tyto třídy mají vlastnosti nenulovatelných primitivních typů (například int v bool jazyce C#), existuje oprava chyby ve verzi 1.1 sady SDK, o které byste měli vědět. Další podrobnosti najdete v opravách chyb ve verzi 1.1 .

Jakmile opravíte všechny chyby sestavení, můžete v aplikaci provádět změny, abyste mohli využívat nové funkce, pokud chcete.

Seznam zásadních změn ve verzi 1.1

Následující seznam je seřazený podle pravděpodobnosti, že změna ovlivní váš kód aplikace.

Změny IndexBatch a IndexAction

IndexBatch.Create byl přejmenován na IndexBatch.New argument a již nemá params argument. Můžete použít IndexBatch.New pro dávky, které kombinují různé typy akcí (sloučení, odstranění atd.). Kromě toho existují nové statické metody pro vytváření dávek, ve kterých jsou všechny akce stejné: Delete, Merge, MergeOrUploada Upload.

IndexAction už nemá veřejné konstruktory a jeho vlastnosti jsou nyní neměnné. Nové statické metody byste měli použít k vytváření akcí pro různé účely: Delete, Merge, MergeOrUpload, a Upload. IndexAction.Create bylo odstraněno. Pokud jste použili přetížení, které přebírá pouze dokument, nezapomeňte místo toho použít prvek Upload.

Příklad

Pokud váš kód vypadá takto:

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

Pokud chcete opravit případné chyby sestavení, můžete ho změnit na toto:

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

Pokud chcete, můžete ho dále zjednodušit:

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

Změny v IndexBatchException

Vlastnost IndexBatchException.IndexResponse byla přejmenována na IndexingResultsa jeho typ je nyní IList<IndexingResult>.

Příklad

Pokud váš kód vypadá takto:

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

Pokud chcete opravit případné chyby sestavení, můžete ho změnit na toto:

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

Změny metody operace

Každá operace v .NET SDK pro Azure Search je vystavena jako sada přetížených metod pro synchronní a asynchronní volání. Podpisy a struktura těchto přetížení metod se změnily ve verzi 1.1.

Například operace Získat statistiku indexu ve starších verzích sady SDK odhalila tyto podpisy:

V IIndexOperations:

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

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

Podpisy metody pro stejnou operaci ve verzi 1.1 vypadají takto:

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

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

Počínaje verzí 1.1 sada .NET SDK služby Azure Search uspořádá metody operací odlišně:

  • Volitelné parametry jsou nyní modelovány jako výchozí parametry, nikoli jako další přetížení metody. To snižuje počet přetížení metod, někdy dramaticky.
  • Metody rozšíření teď před volajícím skryjí spoustu nadbytečných podrobností protokolu HTTP. Například starší verze sady SDK vrátily objekt odpovědi se stavovým kódem HTTP, který jste často nemuseli kontrolovat, protože metody operací můžou CloudException vyvolat jakýkoli stavový kód, který značí chybu. Nové metody rozšíření pouze vracejí objekty modelu, což vám ušetří potíže s jejich rozbalení v kódu.
  • Naopak základní rozhraní teď zpřístupňují metody, které poskytují větší kontrolu na úrovni HTTP, pokud ho potřebujete. Teď můžete do požadavků zahrnout vlastní HTTP hlavičky a nový návratový typ AzureOperationResponse<T> vám poskytne přímý přístup k HttpRequestMessage a HttpResponseMessage pro operaci. AzureOperationResponse je definován v Microsoft.Rest.Azure oboru názvů a nahrazuje Hyak.Common.OperationResponse.

Změny parametrů bodování

Do nejnovější sady SDK byla přidána nová třída s názvem ScoringParameter , která usnadňuje zadávání parametrů pro bodovací profily ve vyhledávacím dotazu. ScoringProfiles vlastnost SearchParameters třídy byla dříve typována jako IList<string>; Nyní je typována jako IList<ScoringParameter>.

Příklad

Pokud váš kód vypadá takto:

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

Pokud chcete opravit případné chyby sestavení, můžete ho změnit na toto:

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

Změny třídy modelu

Vzhledem ke změnám podpisů popsaným v změnách metod operací bylo mnoho tříd v Microsoft.Azure.Search.Models oboru názvů přejmenováno nebo odstraněno. Například:

  • IndexDefinitionResponse byla nahrazena AzureOperationResponse<Index>
  • Přejmenování DocumentSearchResponse na DocumentSearchResult
  • Přejmenování IndexResult na IndexingResult
  • Documents.Count() Nyní vrátí long hodnotu s počtem dokumentů místo hodnoty DocumentCountResponse
  • Přejmenování IndexGetStatisticsResponse na IndexGetStatisticsResult
  • Přejmenování IndexListResponse na IndexListResult

Pro shrnutí byly odebrány třídy odvozené z OperationResponse, které existovaly pouze k zabalení objektu modelu. Zbývající třídy měly jejich příponu změněnou z Response na Result.

Příklad

Pokud váš kód vypadá takto:

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;

Pokud chcete opravit případné chyby sestavení, můžete ho změnit na toto:

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;

Třídy odpovědí a IEnumerable

Další změna, která může ovlivnit váš kód, je, že třídy odpovědí, které obsahují kolekce, již neimplementují IEnumerable<T>. Místo toho můžete k vlastnosti kolekce přistupovat přímo. Pokud například váš kód vypadá takto:

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

Pokud chcete opravit případné chyby sestavení, můžete ho změnit na toto:

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

Speciální případ pro webové aplikace

Pokud máte webovou aplikaci, která serializuje DocumentSearchResponse přímo pro odesílání výsledků hledání do prohlížeče, budete muset změnit kód nebo výsledky nebudou serializovány správně. Pokud například váš kód vypadá takto:

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

Můžete ho změnit tak, že získáte .Results vlastnost odpovědi hledání a opravíte vykreslování výsledků hledání:

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

Tyto případy budete muset hledat ve svém kódu sami; Kompilátor vás nebude varovat , protože JsonResult.Data je typu object.

Změny cloudexceptionu

Třída CloudException se přesunula z oboru názvů Hyak.Common do oboru názvů Microsoft.Rest.Azure. Error Jeho vlastnost byla také přejmenována na Body.

Změny SearchServiceClient a SearchIndexClient

Typ Credentials vlastnosti se změnil z SearchCredentials jeho základní třídy, ServiceClientCredentials. Pokud potřebujete přístup k SearchCredentialsSearchIndexClient nebo SearchServiceClient, použijte novou vlastnost SearchCredentials.

Ve starších verzích sady SDK měly SearchServiceClient a SearchIndexClient konstruktory, které přijímaly parametr HttpClient. Ty byly nahrazeny konstruktory, které přijímají HttpClientHandler a pole objektů typu DelegatingHandler. To usnadňuje instalaci vlastních obslužných rutin pro předběžné zpracování požadavků HTTP v případě potřeby.

Nakonec se změnily konstruktory, které vzaly Uri a SearchCredentials. Pokud máte například kód, který vypadá takto:

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

Pokud chcete opravit případné chyby sestavení, můžete ho změnit na toto:

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

Všimněte si také, že typ parametru přihlašovacích údajů se změnil na ServiceClientCredentials. To není pravděpodobné, že by to ovlivnilo váš kód, protože SearchCredentials je odvozen z ServiceClientCredentials.

Předání ID požadavku

Ve starších verzích sady SDK jste mohli nastavit ID požadavku na SearchServiceClient nebo SearchIndexClient a bylo by zahrnuto do každé žádosti k REST API. To je užitečné při řešení potíží s vyhledávací službou, pokud potřebujete kontaktovat podporu. Je ale užitečnější nastavit jedinečné ID požadavku pro každou operaci, nikoli použít stejné ID pro všechny operace. Z tohoto důvodu byly metody SetClientRequestId, SearchServiceClient a SearchIndexClient odebrány. Místo toho můžete předat ID požadavku každé metodě operace prostřednictvím volitelného SearchRequestOptions parametru.

Poznámka:

V budoucí verzi sady SDK přidáme nový mechanismus pro globální nastavení ID požadavku na objekty klienta, které jsou konzistentní s přístupem používaným jinými sadami SDK Azure.

Příklad

Pokud máte kód, který vypadá takto:

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

Pokud chcete opravit případné chyby sestavení, můžete ho změnit na toto:

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

Změny názvu rozhraní

Názvy rozhraní skupiny operací se změnily tak, aby byly konzistentní s odpovídajícími názvy vlastností:

  • Typ ISearchServiceClient.Indexes byl přejmenován z IIndexOperations na IIndexesOperations.
  • Typ ISearchServiceClient.Indexers byl přejmenován z IIndexerOperations na IIndexersOperations.
  • Typ ISearchServiceClient.DataSources byl přejmenován z IDataSourceOperations na IDataSourcesOperations.
  • Typ ISearchIndexClient.Documents byl přejmenován z IDocumentOperations na IDocumentsOperations.

Tato změna pravděpodobně neovlivní váš kód, pokud jste nevytvořili napodobení těchto rozhraní pro účely testování.

Opravy chyb ve verzi 1.1

Ve starších verzích sady .NET SDK služby Azure Search došlo k chybě související se serializací vlastních tříd modelů. K chybě může dojít, pokud jste vytvořili vlastní třídu modelu s vlastností typu hodnoty, která není nullable.

Kroky pro reprodukci

Vytvořte vlastní třídu modelu s vlastností typu hodnoty, která není nullable. Můžete například přidat veřejnou UnitCount vlastnost typu int místo int?.

Pokud indexujete dokument s výchozí hodnotou tohoto typu (například 0 pro int), bude pole ve službě Azure Search null. Pokud následně vyhledáte tento dokument, Search volání vyvolá JsonSerializationException s tím, že nelze převést null na int.

Filtry také nemusí fungovat podle očekávání, protože hodnota null byla zapsána do indexu místo zamýšlené hodnoty.

Oprava podrobností

Tento problém jsme opravili ve verzi 1.1 sady SDK. Pokud teď máte třídu modelu takto:

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

    public int IntValue { get; set; }
}

a nastavíte IntValue hodnotu 0, tato hodnota je nyní správně serializována jako 0 na drátu a uložena jako 0 v indexu. Round-trip také funguje podle očekávání.

S tímto přístupem je možné zjistit jeden potenciální problém: Pokud používáte typ modelu s nenulovou vlastností, musíte zaručit , že žádné dokumenty v indexu neobsahují hodnotu null pro odpovídající pole. Sada SDK ani rozhraní REST API služby Azure Search vám s tímto vynucením nepomůžou.

Nejedná se jen o hypotetický problém: Představte si scénář, ve kterém přidáte nové pole do existujícího indexu, který je typu Edm.Int32. Po aktualizaci definice indexu budou mít všechny dokumenty hodnotu null pro toto nové pole (protože všechny typy mají ve službě Azure Search hodnotu null). Pokud pak použijete třídu modelu s nenulovou vlastností int pro toto pole, při pokusu o načtení dokumentů získáte JsonSerializationException podobné tomuto:

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

Z tohoto důvodu stále doporučujeme používat typy s možnou hodnotou null ve třídách modelu jako osvědčený postup.

Další podrobnosti o této chybě a opravě najdete v tomto problému na GitHubu.