Uaktualnianie do zestawu .NET SDK usługi Azure Search w wersji 1.1
Jeśli używasz wersji 1.0.2-preview lub starszej zestawu .NET SDK usługi Azure Search, ten artykuł pomoże Ci uaktualnić aplikację do korzystania z wersji 1.1.
Aby zapoznać się z bardziej ogólnym przewodnikiem po zestawie SDK, w tym przykładami, zobacz How to use Azure Search from a .NET Application (Jak używać usługi Azure Search z poziomu aplikacji .NET).
Uwaga
Po uaktualnieniu do wersji 1.1 lub jeśli używasz już wersji od 1.1 do 2.0 w wersji zapoznawczej, należy przeprowadzić uaktualnienie do wersji 3. Aby uzyskać instrukcje, zobacz Uaktualnianie do zestawu .NET SDK usługi Azure Search w wersji 3 .
Najpierw zaktualizuj odwołanie do NuGet przy Microsoft.Azure.Search
użyciu konsoli NuGet Menedżer pakietów lub klikając prawym przyciskiem myszy odwołania do projektu i wybierając pozycję "Zarządzaj pakietami NuGet..." w Visual Studio.
Po NuGet pobrać nowe pakiety i ich zależności ponownie skompiluj projekt.
Jeśli wcześniej używano wersji 1.0.0-preview, 1.0.1-preview lub 1.0.2-preview, kompilacja powinna zakończyć się pomyślnie i wszystko będzie gotowe!
Jeśli wcześniej używano wersji 0.13.0-preview lub starszej, powinny zostać wyświetlone błędy kompilacji podobne do następujących:
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?)
Następnym krokiem jest naprawienie błędów kompilacji jeden po drugim. Większość będzie wymagać zmiany niektórych nazw klas i metod, które zostały zmienione w zestawie SDK. Lista zmian powodujących niezgodność w wersji 1.1 zawiera listę tych zmian nazw.
Jeśli używasz klas niestandardowych do modelowania dokumentów, a te klasy mają właściwości typów pierwotnych nienależących do wartości null (na przykład int
lub bool
w języku C#), w wersji 1.1 zestawu SDK należy pamiętać. Aby uzyskać więcej informacji, zobacz Poprawki błędów w wersji 1.1 .
Na koniec po usunięciu błędów kompilacji możesz wprowadzić zmiany w aplikacji, aby skorzystać z nowych funkcji, jeśli chcesz.
Lista zmian powodujących niezgodność w wersji 1.1
Poniższa lista jest uporządkowana według prawdopodobieństwa, że zmiana wpłynie na kod aplikacji.
Zmiany IndexBatch i IndexAction
IndexBatch.Create
zmieniono nazwę na IndexBatch.New
i nie ma już argumentu params
. Można użyć IndexBatch.New
dla partii, które mieszają różne typy akcji (scalania, usuwania itp.). Ponadto istnieją nowe metody statyczne do tworzenia partii, w których wszystkie akcje są takie same: Delete
, , Merge
MergeOrUpload
i Upload
.
IndexAction
Nie ma już publicznych konstruktorów, a jego właściwości są teraz niezmienne. Należy użyć nowych metod statycznych do tworzenia akcji dla różnych celów: Delete
, , Merge
MergeOrUpload
, i Upload
.
IndexAction.Create
został usunięty. Jeśli użyto przeciążenia, które pobiera tylko dokument, pamiętaj, aby zamiast tego użyć Upload
.
Przykład
Jeśli kod wygląda następująco:
var batch = IndexBatch.Create(documents.Select(doc => IndexAction.Create(doc)));
indexClient.Documents.Index(batch);
Możesz ją zmienić, aby naprawić błędy kompilacji:
var batch = IndexBatch.New(documents.Select(doc => IndexAction.Upload(doc)));
indexClient.Documents.Index(batch);
Jeśli chcesz, możesz jeszcze bardziej uprościć ten proces:
var batch = IndexBatch.Upload(documents);
indexClient.Documents.Index(batch);
Zmiany indexBatchException
Nazwa IndexBatchException.IndexResponse
właściwości została zmieniona na IndexingResults
, a jej typ to teraz IList<IndexingResult>
.
Przykład
Jeśli kod wygląda następująco:
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)));
}
Możesz ją zmienić, aby naprawić błędy kompilacji:
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)));
}
Zmiany metody operacji
Każda operacja w zestawie .NET SDK usługi Azure Search jest uwidaczniona jako zestaw przeciążeń metod synchronicznych i asynchronicznych. Podpisy i faktoring tych przeciążeń metody zmieniły się w wersji 1.1.
Na przykład operacja "Pobierz statystyki indeksu" w starszych wersjach zestawu SDK uwidoczniła następujące podpisy:
W pliku IIndexOperations
:
// Asynchronous operation with all parameters
Task<IndexGetStatisticsResponse> GetStatisticsAsync(
string indexName,
CancellationToken cancellationToken);
W pliku 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 dla tej samej operacji w wersji 1.1 wyglądają następująco:
W pliku 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));
W pliku 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));
Począwszy od wersji 1.1, zestaw .NET SDK usługi Azure Search organizuje metody operacji inaczej:
- Parametry opcjonalne są teraz modelowane jako parametry domyślne, a nie dodatkowe przeciążenia metody. Zmniejsza to liczbę przeciążeń metody, czasami dramatycznie.
- Metody rozszerzenia ukrywają teraz wiele nadmiarowych szczegółów protokołu HTTP od obiektu wywołującego. Na przykład starsze wersje zestawu SDK zwróciły obiekt odpowiedzi z kodem stanu HTTP, którego często nie trzeba sprawdzać, ponieważ metody operacji zgłaszają
CloudException
dowolny kod stanu wskazujący błąd. Nowe metody rozszerzenia po prostu zwracają obiekty modelu, co pozwala zaoszczędzić problemy z koniecznością odpakowania ich w kodzie. - Z drugiej strony, podstawowe interfejsy teraz uwidaczniają metody, które zapewniają większą kontrolę na poziomie HTTP, jeśli jest to potrzebne. Teraz można przekazywać niestandardowe nagłówki HTTP, które mają być uwzględniane w żądaniach, a nowy
AzureOperationResponse<T>
typ zwracania zapewnia bezpośredni dostęp do elementówHttpRequestMessage
iHttpResponseMessage
dla operacji.AzureOperationResponse
element jest zdefiniowany wMicrosoft.Rest.Azure
przestrzeni nazw i zastępuje wartośćHyak.Common.OperationResponse
.
Zmiany parametrów oceniania
W najnowszym zestawie SDK dodano nową klasę o nazwie ScoringParameter
, aby ułatwić udostępnianie parametrów profilom oceniania w zapytaniu wyszukiwania.
ScoringProfiles
Wcześniej właściwość SearchParameters
klasy została wpisana jako IList<string>
; Teraz jest on wpisany jako IList<ScoringParameter>
.
Przykład
Jeśli kod wygląda następująco:
var sp = new SearchParameters();
sp.ScoringProfile = "jobsScoringFeatured"; // Use a scoring profile
sp.ScoringParameters = new[] { "featuredParam-featured", "mapCenterParam-" + lon + "," + lat };
Możesz ją zmienić, aby naprawić błędy kompilacji:
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))
};
Zmiany klas modelu
Ze względu na zmiany podpisu opisane w sekcji Zmiany metody operacji wiele klas w Microsoft.Azure.Search.Models
przestrzeni nazw zostało zmienionych lub usuniętych. Przykład:
-
IndexDefinitionResponse
został zastąpiony przezAzureOperationResponse<Index>
- Zmieniono nazwę polecenia
DocumentSearchResponse
naDocumentSearchResult
- Zmieniono nazwę polecenia
IndexResult
naIndexingResult
-
Documents.Count()
teraz zwraca wartośćlong
z liczbą dokumentów zamiastDocumentCountResponse
- Zmieniono nazwę polecenia
IndexGetStatisticsResponse
naIndexGetStatisticsResult
- Zmieniono nazwę polecenia
IndexListResponse
naIndexListResult
Podsumowując, OperationResponse
klasy pochodne, które istniały tylko do opakowywania obiektu modelu, zostały usunięte. Pozostałe klasy zmieniły sufiks z Response
na Result
.
Przykład
Jeśli kod wygląda następująco:
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;
Możesz ją zmienić, aby naprawić błędy kompilacji:
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;
Klasy odpowiedzi i IEnumerable
Dodatkową zmianą, która może mieć wpływ na kod, jest to, że klasy odpowiedzi, które przechowują kolekcje, nie implementują już elementu IEnumerable<T>
. Zamiast tego możesz bezpośrednio uzyskać dostęp do właściwości kolekcji. Jeśli na przykład kod wygląda następująco:
DocumentSearchResponse<Hotel> response = indexClient.Documents.Search<Hotel>(searchText, sp);
foreach (SearchResult<Hotel> result in response)
{
Console.WriteLine(result.Document);
}
Możesz ją zmienić, aby naprawić błędy kompilacji:
DocumentSearchResult<Hotel> response = indexClient.Documents.Search<Hotel>(searchText, sp);
foreach (SearchResult<Hotel> result in response.Results)
{
Console.WriteLine(result.Document);
}
Specjalny przypadek dla aplikacji internetowych
Jeśli masz aplikację internetową, która serializuje DocumentSearchResponse
się bezpośrednio w celu wysyłania wyników wyszukiwania do przeglądarki, musisz zmienić kod lub wyniki nie będą serializować poprawnie. Jeśli na przykład kod wygląda następująco:
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)
};
}
Możesz ją zmienić, uzyskując .Results
właściwość odpowiedzi wyszukiwania, aby naprawić renderowanie wyników wyszukiwania:
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
};
}
W kodzie trzeba będzie samodzielnie wyszukać takie przypadki; Kompilator nie wyświetli ostrzeżenia , ponieważ JsonResult.Data
jest typu object
.
Zmiany cloudException
Klasa CloudException
została przeniesiona Hyak.Common
z przestrzeni nazw do Microsoft.Rest.Azure
przestrzeni nazw. Ponadto jej Error
właściwość została zmieniona na Body
.
Zmiany elementu SearchServiceClient i SearchIndexClient
Typ Credentials
właściwości zmienił się z SearchCredentials
na jej klasę bazową . ServiceClientCredentials
Jeśli musisz uzyskać dostęp SearchCredentials
do obiektu SearchIndexClient
lub SearchServiceClient
, użyj nowej SearchCredentials
właściwości.
W starszych wersjach zestawu SDK i SearchIndexClient
miał konstruktory, SearchServiceClient
które miały HttpClient
parametr. Zostały one zastąpione konstruktorami, które przyjmują tablicę HttpClientHandler
DelegatingHandler
obiektów i . Ułatwia to instalowanie niestandardowych procedur obsługi w celu wstępnego przetwarzania żądań HTTP w razie potrzeby.
Na koniec konstruktory, które miały Uri
element i SearchCredentials
uległy zmianie. Jeśli na przykład masz kod, który wygląda następująco:
var client =
new SearchServiceClient(
new SearchCredentials("abc123"),
new Uri("http://myservice.search.windows.net"));
Możesz ją zmienić, aby naprawić błędy kompilacji:
var client =
new SearchServiceClient(
new Uri("http://myservice.search.windows.net"),
new SearchCredentials("abc123"));
Należy również pamiętać, że typ parametru poświadczeń został zmieniony na ServiceClientCredentials
. Jest to mało prawdopodobne, aby wpłynąć na kod, ponieważ SearchCredentials
pochodzi z .ServiceClientCredentials
Przekazywanie identyfikatora żądania
W starszych wersjach zestawu SDK można ustawić identyfikator żądania dla SearchServiceClient
elementu lub SearchIndexClient
i będzie on uwzględniany w każdym żądaniu do interfejsu API REST. Jest to przydatne w przypadku rozwiązywania problemów z usługą wyszukiwania, jeśli musisz skontaktować się z pomocą techniczną. Jednak bardziej przydatne jest ustawienie unikatowego identyfikatora żądania dla każdej operacji, a nie użycie tego samego identyfikatora dla wszystkich operacji. Z tego powodu SetClientRequestId
metody SearchServiceClient
i SearchIndexClient
zostały usunięte. Zamiast tego można przekazać identyfikator żądania do każdej metody operacji za pomocą opcjonalnego SearchRequestOptions
parametru.
Uwaga
W przyszłej wersji zestawu SDK dodamy nowy mechanizm ustawiania identyfikatora żądania globalnie na obiektach klienta, które są zgodne z podejściem używanym przez inne zestawy SDK platformy Azure.
Przykład
Jeśli masz kod, który wygląda następująco:
client.SetClientRequestId(Guid.NewGuid());
...
long count = client.Documents.Count();
Możesz ją zmienić, aby naprawić błędy kompilacji:
long count = client.Documents.Count(new SearchRequestOptions(requestId: Guid.NewGuid()));
Zmiany nazwy interfejsu
Nazwy interfejsów grupy operacji zostały zmienione tak, aby były zgodne z odpowiednimi nazwami właściwości:
- Nazwa typu
ISearchServiceClient.Indexes
została zmieniona zIIndexOperations
naIIndexesOperations
. - Nazwa typu
ISearchServiceClient.Indexers
została zmieniona zIIndexerOperations
naIIndexersOperations
. - Nazwa typu
ISearchServiceClient.DataSources
została zmieniona zIDataSourceOperations
naIDataSourcesOperations
. - Nazwa typu
ISearchIndexClient.Documents
została zmieniona zIDocumentOperations
naIDocumentsOperations
.
Ta zmiana prawdopodobnie nie wpłynie na kod, chyba że utworzono makiety tych interfejsów do celów testowych.
Poprawki błędów w wersji 1.1
W starszych wersjach zestawu .NET SDK usługi Azure Search wystąpił błąd związany z serializacji niestandardowych klas modelu. Usterka może wystąpić, jeśli utworzono niestandardową klasę modelu z właściwością typu wartości innej niż null.
Kroki odtwarzania
Utwórz niestandardową klasę modelu z właściwością typu wartości innej niż null. Na przykład dodaj właściwość publiczną UnitCount
typu int
zamiast int?
.
Jeśli zaindeksujesz dokument z wartością domyślną tego typu (na przykład 0 dla int
), pole będzie mieć wartość null w usłudze Azure Search. Jeśli następnie wyszukasz ten dokument, Search
wywołanie zgłosi JsonSerializationException
zgłoszenie, że nie będzie można przekonwertować null
go na int
.
Ponadto filtry mogą nie działać zgodnie z oczekiwaniami, ponieważ wartość null została zapisana w indeksie zamiast zamierzonej wartości.
Poprawka szczegółów
Rozwiązaliśmy ten problem w wersji 1.1 zestawu SDK. Teraz, jeśli masz klasę modelu w następujący sposób:
public class Model
{
public string Key { get; set; }
public int IntValue { get; set; }
}
i ustawiono IntValue
wartość 0, ta wartość jest teraz poprawnie serializowana jako 0 w przewodzie i przechowywana jako 0 w indeksie. Zaokrąglanie działa również zgodnie z oczekiwaniami.
Istnieje jeden z potencjalnych problemów, o których należy pamiętać przy użyciu tego podejścia: jeśli używasz typu modelu z właściwością niepustą, musisz zagwarantować , że żadne dokumenty w indeksie nie zawierają wartości null dla odpowiedniego pola. Ani zestaw SDK, ani interfejs API REST usługi Azure Search nie pomogą Ci wymusić tego.
Nie jest to czysto hipotetyczny problem: wyobraź sobie scenariusz, w którym dodajesz nowe pole do istniejącego indeksu typu Edm.Int32
. Po zaktualizowaniu definicji indeksu wszystkie dokumenty będą miały wartość null dla tego nowego pola (ponieważ wszystkie typy w usłudze Azure Search dopuszczają wartość null). Jeśli następnie dla tego pola użyjesz klasy modelu z właściwością int
niedopuszczającą wartości null, podczas próby pobrania dokumentów otrzymasz wyjątek JsonSerializationException
podobny do poniższego:
Error converting value {null} to type 'System.Int32'. Path 'IntValue'.
Z tego powodu nadal zalecamy używanie typów dopuszczających wartość null w klasach modelu jako najlepsze rozwiązanie.
Aby uzyskać więcej informacji na temat tej usterki i poprawki, zobacz ten problem w GitHub.