Jak používat Microsoft.Azure.Search v aplikaci C# .NET
Tento článek vysvětluje, jak vytvářet a spravovat vyhledávací objekty pomocí jazyka C# a starší klientské knihovny Microsoft.Azure.Search (verze 10) v sadě Azure SDK pro .NET.
Verze 10 je poslední verzí balíčku Microsoft.Azure.Search. V budoucnu se nové funkce zavedou v Azure.Search.Documents z týmu sady Azure SDK.
Poznámka
Pokud máte existující nebo letové vývojové projekty, můžete i nadále používat verzi 10. V případě nových projektů nebo použití nových funkcí byste měli přejít na novou knihovnu.
Informace o verzi 10
Sada SDK se skládá z několika klientských knihoven, které umožňují spravovat indexy, zdroje dat, indexery a mapy synonym, stejně jako nahrávání a správu dokumentů a spouštění dotazů, aniž byste museli řešit podrobnosti protokolu HTTP a JSON. Tyto klientské knihovny se distribuují jako balíčky NuGet.
Hlavním balíčkem NuGet je Microsoft.Azure.Search
metabalíč, který obsahuje všechny ostatní balíčky jako závislosti. Tento balíček použijte, pokud právě začínáte nebo pokud víte, že vaše aplikace bude potřebovat všechny funkce Azure Cognitive Search.
Ostatní balíčky NuGet v sadě SDK jsou:
-
Microsoft.Azure.Search.Data
: Tento balíček použijte, pokud vyvíjíte aplikaci .NET pomocí Azure Cognitive Search a potřebujete pouze dotazovat nebo aktualizovat dokumenty v indexech. Pokud také potřebujete vytvořit nebo aktualizovat indexy, mapy synonym nebo jiné prostředky na úrovni služby, použijteMicrosoft.Azure.Search
balíček. -
Microsoft.Azure.Search.Service
: Tento balíček použijte, pokud vyvíjíte automatizaci v .NET ke správě Azure Cognitive Search indexů, map synonym, indexerů, zdrojů dat nebo jiných prostředků na úrovni služby. Pokud potřebujete dotazovat nebo aktualizovat dokumenty jenom v indexech, použijteMicrosoft.Azure.Search.Data
balíček. Pokud potřebujete všechny funkce Azure Cognitive Search, použijteMicrosoft.Azure.Search
místo toho balíček. -
Microsoft.Azure.Search.Common
: Běžné typy potřebné pro knihovny Azure Cognitive Search .NET. Tento balíček nemusíte používat přímo ve své aplikaci. Je určen pouze k použití jako závislosti.
Různé klientské knihovny definují třídy, jako jsou Index
, Field
a Document
, a také operace jako Indexes.Create
a Documents.Search
třídy SearchServiceClient
SearchIndexClient
. Tyto třídy jsou uspořádané do následujících oborů názvů:
Pokud chcete poskytnout zpětnou vazbu k budoucí aktualizaci sady SDK, podívejte se na naši stránku pro zpětnou vazbu nebo vytvořte problém s GitHub a v názvu problému uveďte "Azure Cognitive Search".
Sada .NET SDK cílí na verzi2019-05-06
rozhraní AZURE COGNITIVE SEARCH REST API. Tato verze zahrnuje podporu komplexních typů, rozšiřování AI, automatického dokončování a režimu parsování JsonLines při indexování objektů blob Azure.
Tato sada SDK nepodporuje operace správy , jako je vytváření a škálování vyhledávacích služeb a správa klíčů rozhraní API. Pokud potřebujete spravovat prostředky vyhledávání z aplikace .NET, můžete použít sadu Azure Cognitive Search .NET Management SDK.
Upgrade na verzi 10
Pokud už používáte starší verzi sady Azure Cognitive Search .NET SDK a chcete upgradovat na nejnovější obecně dostupnou verzi, tento článek vysvětluje, jak na to.
Požadavky na sadu SDK
- Visual Studio 2017 nebo novější.
- Vaše vlastní služba Azure Cognitive Search. Abyste mohli sadu SDK používat, budete potřebovat název služby a jeden nebo více klíčů rozhraní API. Tento postup vám pomůže vytvořit službu na portálu.
- Stáhněte balíček Azure Cognitive Search .NET SDK NuGet pomocí příkazu Spravovat balíčky NuGet v Visual Studio. Stačí vyhledat název
Microsoft.Azure.Search
balíčku na NuGet.org (nebo jeden z dalších názvů balíčků výše, pokud potřebujete jenom podmnožinu funkcí).
Sada Azure Cognitive Search .NET SDK podporuje aplikace, které cílí na rozhraní .NET Framework 4.5.2 a vyšší, stejně jako .NET Core 2.0 a vyšší.
Základní scénáře
Ve vyhledávací aplikaci budete muset udělat několik věcí. V tomto kurzu se podíváme na tyto základní scénáře:
- Vytvoření indexu
- Naplnění indexu dokumenty
- Hledání dokumentů pomocí fulltextového vyhledávání a filtrů
Následující ukázkový kód znázorňuje každý z těchto scénářů. Můžete použít fragmenty kódu ve vlastní aplikaci.
Přehled
Ukázková aplikace, která prozkoumáme, vytvoří nový index s názvem "hotely", naplní ho několika dokumenty a pak provede některé vyhledávací dotazy. Tady je hlavní program zobrazující celkový tok:
// This sample shows how to delete, create, upload documents and query an index
static void Main(string[] args)
{
IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
IConfigurationRoot configuration = builder.Build();
SearchServiceClient serviceClient = CreateSearchServiceClient(configuration);
string indexName = configuration["SearchIndexName"];
Console.WriteLine("{0}", "Deleting index...\n");
DeleteIndexIfExists(indexName, serviceClient);
Console.WriteLine("{0}", "Creating index...\n");
CreateIndex(indexName, serviceClient);
ISearchIndexClient indexClient = serviceClient.Indexes.GetClient(indexName);
Console.WriteLine("{0}", "Uploading documents...\n");
UploadDocuments(indexClient);
ISearchIndexClient indexClientForQueries = CreateSearchIndexClient(configuration);
RunQueries(indexClientForQueries);
Console.WriteLine("{0}", "Complete. Press any key to end application...\n");
Console.ReadKey();
}
Poznámka
Úplný zdrojový kód ukázkové aplikace použité v tomto názorném postupu najdete na Githubu.
Projdeme si tento krok za krokem. Nejprve musíme vytvořit novou SearchServiceClient
. Tento objekt umožňuje spravovat indexy. Abyste mohli vytvořit jednu, musíte zadat název služby Azure Cognitive Search i klíč rozhraní API pro správu. Tyto informace můžete zadat do appsettings.json
souboru ukázkové aplikace.
private static SearchServiceClient CreateSearchServiceClient(IConfigurationRoot configuration)
{
string searchServiceName = configuration["SearchServiceName"];
string adminApiKey = configuration["SearchServiceAdminApiKey"];
SearchServiceClient serviceClient = new SearchServiceClient(searchServiceName, new SearchCredentials(adminApiKey));
return serviceClient;
}
Poznámka
Pokud zadáte nesprávný klíč (například klíč dotazu, kde byl vyžadován klíč správce), SearchServiceClient
zobrazí CloudException
se chybová zpráva "Zakázáno" při prvním volání metody operace, například Indexes.Create
. Pokud k tomu dojde, pečlivě zkontrolujte náš klíč rozhraní API.
Několik dalších řádků volá metody volání vytvořit index s názvem "hotely", odstranit ho nejprve, pokud již existuje. Tyto metody si projdeme o něco později.
Console.WriteLine("{0}", "Deleting index...\n");
DeleteIndexIfExists(indexName, serviceClient);
Console.WriteLine("{0}", "Creating index...\n");
CreateIndex(indexName, serviceClient);
V dalším kroku je potřeba index naplnit. K naplnění indexu budeme potřebovat SearchIndexClient
. Existují dva způsoby, jak jednu získat: vytvořením nebo voláním Indexes.GetClient
.SearchServiceClient
Používáme je pro pohodlí.
ISearchIndexClient indexClient = serviceClient.Indexes.GetClient(indexName);
Poznámka
V typické aplikaci vyhledávání může správa indexů a populace zpracovávat samostatnou komponentu od vyhledávacích dotazů.
Indexes.GetClient
je vhodné pro naplnění indexu, protože vám ušetří potíže s poskytnutím dalších SearchCredentials
. Dělá to pomocí předání klíče správce, který jste použili pro vytvoření SearchServiceClient
, službě SearchIndexClient
. V části aplikace, která provádí dotazy, je ale lepší vytvořit SearchIndexClient
přímo, abyste mohli předat klíč dotazu, který umožňuje číst data jenom místo klíče správce. To je konzistentní s principem minimálního oprávnění a pomůže vám to lépe zabezpečit vaši aplikaci. Další informace o klíčích správce a klíčích dotazů najdete tady.
Teď, když máme SearchIndexClient
, můžeme naplnit index. Počet indexů se provádí jinou metodou, kterou si projdeme později.
Console.WriteLine("{0}", "Uploading documents...\n");
UploadDocuments(indexClient);
Nakonec provedeme několik vyhledávacích dotazů a zobrazíme výsledky. Tentokrát používáme jinou SearchIndexClient
:
ISearchIndexClient indexClientForQueries = CreateSearchIndexClient(indexName, configuration);
RunQueries(indexClientForQueries);
Později se podrobněji podíváme na metodu RunQueries
. Tady je kód pro vytvoření nové SearchIndexClient
:
private static SearchIndexClient CreateSearchIndexClient(string indexName, IConfigurationRoot configuration)
{
string searchServiceName = configuration["SearchServiceName"];
string queryApiKey = configuration["SearchServiceQueryApiKey"];
SearchIndexClient indexClient = new SearchIndexClient(searchServiceName, indexName, new SearchCredentials(queryApiKey));
return indexClient;
}
Tentokrát použijeme klíč dotazu, protože k indexu nepotřebujeme přístup k zápisu. Tyto informace můžete zadat do appsettings.json
souboru ukázkové aplikace.
Pokud spustíte tuto aplikaci s platným názvem služby a klíči rozhraní API, měl by výstup vypadat jako v tomto příkladu: (Některé výstupy konzoly byly nahrazeny znakem "..." pro ilustraci.)
Deleting index...
Creating index...
Uploading documents...
Waiting for documents to be indexed...
Search the entire index for the term 'motel' and return only the HotelName field:
Name: Secret Point Motel
Name: Twin Dome Motel
Apply a filter to the index to find hotels with a room cheaper than $100 per night, and return the hotelId and description:
HotelId: 1
Description: The hotel is ideally located on the main commercial artery of the city in the heart of New York. A few minutes away is Times Square and the historic centre of the city, as well as other places of interest that make New York one of America's most attractive and cosmopolitan cities.
HotelId: 2
Description: The hotel is situated in a nineteenth century plaza, which has been expanded and renovated to the highest architectural standards to create a modern, functional and first-class hotel in which art and unique historical elements coexist with the most modern comforts.
Search the entire index, order by a specific field (lastRenovationDate) in descending order, take the top two results, and show only hotelName and lastRenovationDate:
Name: Triple Landscape Hotel
Last renovated on: 9/20/2015 12:00:00 AM +00:00
Name: Twin Dome Motel
Last renovated on: 2/18/1979 12:00:00 AM +00:00
Search the hotel names for the term 'hotel':
HotelId: 3
Name: Triple Landscape Hotel
...
Complete. Press any key to end application...
Úplný zdrojový kód aplikace je k dispozici na konci tohoto článku.
Dále se podrobněji podíváme na každou metodu, kterou Main
volá .
Vytvoření indexu
Po vytvoření SearchServiceClient
souboru odstraní index "hotels", Main
pokud již existuje. Toto odstranění provádí následující metodou:
private static void DeleteIndexIfExists(string indexName, SearchServiceClient serviceClient)
{
if (serviceClient.Indexes.Exists(indexName))
{
serviceClient.Indexes.Delete(indexName);
}
}
Tato metoda používá danou SearchServiceClient
metodu ke kontrole, jestli index existuje, a pokud ano, odstraňte ho.
Poznámka
Ukázkový kód v tomto článku používá synchronní metody sady Azure Cognitive Search .NET SDK pro zjednodušení. Doporučujeme ve vlastních aplikacích použít asynchronní metody, aby aplikace byly škálovatelné a dobře reagovaly. Například ve výše uvedené metodě můžete použít ExistsAsync
místo DeleteAsync
Exists
a Delete
.
Main
Dále vytvoří nový index "hotels", a to zavoláním této metody:
private static void CreateIndex(string indexName, SearchServiceClient serviceClient)
{
var definition = new Index()
{
Name = indexName,
Fields = FieldBuilder.BuildForType<Hotel>()
};
serviceClient.Indexes.Create(definition);
}
Tato metoda vytvoří nový Index
objekt se seznamem Field
objektů, které definují schéma nového indexu. Každé pole má název, datový typ a několik atributů, které definují chování hledání. Třída FieldBuilder
používá reflexi k vytvoření seznamu Field
objektů pro index prozkoumáním veřejných vlastností a atributů dané Hotel
třídy modelu. Později se podrobněji podíváme na Hotel
třídu.
Poznámka
Seznam Field
objektů můžete vždy vytvořit přímo místo toho, abyste je v případě potřeby používali FieldBuilder
. Například možná nechcete použít třídu modelu nebo budete muset použít existující třídu modelu, kterou nechcete upravovat přidáním atributů.
Kromě polí můžete do indexu přidat také profily bodování, návrhy nebo možnosti CORS (tyto parametry jsou z ukázky vynechány pro stručnost). Další informace o objektu indexu a jeho součástech najdete v referenčních informacích k sadě SDK a také v referenčních informacích k rozhraní REST API Azure Cognitive Search.
Naplnění indexu
Další krok naplní Main
nově vytvořený index. Tento soubor indexu se provádí v následující metodě: (Nějaký kód nahrazený znakem "..." pro ilustraci. Podívejte se na úplné ukázkové řešení pro úplný kód základního souboru dat.)
private static void UploadDocuments(ISearchIndexClient indexClient)
{
var hotels = new Hotel[]
{
new Hotel()
{
HotelId = "1",
HotelName = "Secret Point Motel",
...
Address = new Address()
{
StreetAddress = "677 5th Ave",
...
},
Rooms = new Room[]
{
new Room()
{
Description = "Budget Room, 1 Queen Bed (Cityside)",
...
},
new Room()
{
Description = "Budget Room, 1 King Bed (Mountain View)",
...
},
new Room()
{
Description = "Deluxe Room, 2 Double Beds (City View)",
...
}
}
},
new Hotel()
{
HotelId = "2",
HotelName = "Twin Dome Motel",
...
{
StreetAddress = "140 University Town Center Dr",
...
},
Rooms = new Room[]
{
new Room()
{
Description = "Suite, 2 Double Beds (Mountain View)",
...
},
new Room()
{
Description = "Standard Room, 1 Queen Bed (City View)",
...
},
new Room()
{
Description = "Budget Room, 1 King Bed (Waterfront View)",
...
}
}
},
new Hotel()
{
HotelId = "3",
HotelName = "Triple Landscape Hotel",
...
Address = new Address()
{
StreetAddress = "3393 Peachtree Rd",
...
},
Rooms = new Room[]
{
new Room()
{
Description = "Standard Room, 2 Queen Beds (Amenities)",
...
},
new Room ()
{
Description = "Standard Room, 2 Double Beds (Waterfront View)",
...
},
new Room()
{
Description = "Deluxe Room, 2 Double Beds (Cityside)",
...
}
}
}
};
var batch = IndexBatch.Upload(hotels);
try
{
indexClient.Documents.Index(batch);
}
catch (IndexBatchException e)
{
// Sometimes when your Search service is under load, indexing will fail for some of the documents in
// the batch. Depending on your application, you can take compensating actions like delaying and
// retrying. For this simple demo, we just log the failed document keys and continue.
Console.WriteLine(
"Failed to index some of the documents: {0}",
String.Join(", ", e.IndexingResults.Where(r => !r.Succeeded).Select(r => r.Key)));
}
Console.WriteLine("Waiting for documents to be indexed...\n");
Thread.Sleep(2000);
}
Tato metoda má čtyři části. První vytvoří pole 3 objektů s 3 Hotel
Room
objekty, které budou sloužit jako vstupní data pro nahrání do indexu. Tato data jsou pevně zakódovaná pro jednoduchost. Ve vaší vlastní aplikaci budou vaše data pravděpodobně pocházet z externího zdroje dat, jako je například databáze SQL.
Druhá část vytvoří IndexBatch
obsahující dokumenty. Zadáte operaci, kterou chcete použít pro dávku v době, kdy ji vytvoříte, v tomto případě voláním IndexBatch.Upload
. Dávka se pak nahraje do Azure Cognitive Search indexu metodouDocuments.Index
.
Poznámka
V tomto příkladu právě nahráváme dokumenty. Pokud chcete sloučit změny do existujících dokumentů nebo odstranit dokumenty, můžete vytvořit dávky voláním IndexBatch.Merge
, IndexBatch.MergeOrUpload
nebo IndexBatch.Delete
místo toho. Můžete také kombinovat různé operace v jedné dávce voláním IndexBatch.New
, který přebírá kolekci IndexAction
objektů, z nichž každý říká, Azure Cognitive Search provést konkrétní operaci v dokumentu. Každý IndexAction
můžete vytvořit pomocí vlastní operace voláním odpovídající metody, například IndexAction.Merge
, IndexAction.Upload
atd.
Třetí část této metody je blok catch, který zpracovává důležitý případ chyby pro indexování. Pokud vaše Azure Cognitive Search služba nedokáže indexovat některé dokumenty v dávce, vyvolá se .IndexBatchException
Documents.Index
K této výjimce může dojít v případě, že indexujete dokumenty v době, kdy je vaše služba zatížená velkým zatížením. Důrazně doporučujeme v kódu explicitně zpracovávat tento případ. Indexování dokumentů, které selhaly, můžete odložit a poté zkusit znovu, nebo v závislosti na požadavcích vaší aplikace na konzistenci dat provést něco jiného.
Poznámka
Metodu FindFailedActionsToRetry
můžete použít k vytvoření nové dávky obsahující pouze akce, které selhaly v předchozím volání Index
. Existuje diskuze o tom, jak ho správně používat ve službě StackOverflow.
UploadDocuments
Nakonec metoda zpožďuje dvě sekundy. Indexování probíhá asynchronně ve vaší službě Azure Cognitive Search, takže ukázková aplikace musí chvíli počkat, aby se zajistilo, že jsou dokumenty dostupné pro vyhledávání. Tato odložení se obvykle používají pouze v ukázkových aplikacích a při testech.
Jak .NET SDK zpracovává dokumenty
Možná vás zajímá, jak Azure Cognitive Search .NET SDK dokáže nahrát instance uživatelem definované třídy, jako Hotel
je index. Abychom na tuto otázku mohli odpovědět, podívejme se na Hotel
třídu:
using System;
using Microsoft.Azure.Search;
using Microsoft.Azure.Search.Models;
using Microsoft.Spatial;
using Newtonsoft.Json;
public partial class Hotel
{
[System.ComponentModel.DataAnnotations.Key]
[IsFilterable]
public string HotelId { get; set; }
[IsSearchable, IsSortable]
public string HotelName { get; set; }
[IsSearchable]
[Analyzer(AnalyzerName.AsString.EnLucene)]
public string Description { get; set; }
[IsSearchable]
[Analyzer(AnalyzerName.AsString.FrLucene)]
[JsonProperty("Description_fr")]
public string DescriptionFr { get; set; }
[IsSearchable, IsFilterable, IsSortable, IsFacetable]
public string Category { get; set; }
[IsSearchable, IsFilterable, IsFacetable]
public string[] Tags { get; set; }
[IsFilterable, IsSortable, IsFacetable]
public bool? ParkingIncluded { get; set; }
// SmokingAllowed reflects whether any room in the hotel allows smoking.
// The JsonIgnore attribute indicates that a field should not be created
// in the index for this property and it will only be used by code in the client.
[JsonIgnore]
public bool? SmokingAllowed => (Rooms != null) ? Array.Exists(Rooms, element => element.SmokingAllowed == true) : (bool?)null;
[IsFilterable, IsSortable, IsFacetable]
public DateTimeOffset? LastRenovationDate { get; set; }
[IsFilterable, IsSortable, IsFacetable]
public double? Rating { get; set; }
public Address Address { get; set; }
[IsFilterable, IsSortable]
public GeographyPoint Location { get; set; }
public Room[] Rooms { get; set; }
}
První věc, kterou si všimněte, je, že název každé veřejné vlastnosti ve Hotel
třídě se mapuje na pole se stejným názvem v definici indexu. Pokud chcete, aby každé pole začínalo písmenem malého písmena ("camel case"), můžete sadě SDK říct, aby mapovala názvy vlastností na camel-case automaticky s atributem [SerializePropertyNamesAsCamelCase]
ve třídě. Tento scénář je běžný v aplikacích .NET, které provádějí datovou vazbu, kde je cílové schéma mimo kontrolu vývojáře aplikací, aniž by musely porušit pokyny pro pojmenování "Pascal case" v .NET.
Poznámka
Sada Azure Cognitive Search .NET SDK používá knihovnu NewtonSoft JSON.NET k serializaci a deserializaci objektů vlastního modelu do a z JSON. V případě potřeby lze serializaci přizpůsobit. Další informace najdete v tématu Vlastní serializace s JSON.NET.
Druhá věc, kterou si všimněte, je každá vlastnost zdobena atributy, jako IsFilterable
jsou , IsSearchable
, a Key
Analyzer
. Tyto atributy se mapují přímo na odpovídající atributy pole v indexu Azure Cognitive Search. Třída FieldBuilder
tyto vlastnosti používá k vytvoření definic polí pro index.
Třetí důležitou věcí třídy Hotel
je datové typy veřejných vlastností. .NET typy těchto vlastností se mapují na odpovídající typy polí v definici indexu. Například řetězcová vlastnost Category
se mapuje na pole category
, které je typu Edm.String
. Existují podobné mapování typů mezi bool?
, Edm.Boolean
, DateTimeOffset?
a Edm.DateTimeOffset
tak dále. Konkrétní pravidla mapování typů jsou zdokumentovaná metodou Documents.Get
v odkazu na sadu .NET SDK Azure Cognitive Search. Třída FieldBuilder
se postará o toto mapování za vás, ale přesto může být užitečné pochopit v případě, že potřebujete vyřešit všechny problémy se serializací.
Všimli jste si nemovitosti SmokingAllowed
?
[JsonIgnore]
public bool? SmokingAllowed => (Rooms != null) ? Array.Exists(Rooms, element => element.SmokingAllowed == true) : (bool?)null;
Atribut JsonIgnore
pro tuto vlastnost říká, aby FieldBuilder
ho serializoval do indexu jako pole. To je skvělý způsob, jak vytvořit počítané vlastnosti na straně klienta, které můžete použít jako pomocné rutiny ve vaší aplikaci. V tomto případě vlastnost odráží, SmokingAllowed
zda jakákoliv Room
kolekce Rooms
umožňuje kouření. Pokud jsou všechny nepravdivé, znamená to, že celý hotel neumožňuje kouření.
Některé vlastnosti, jako Address
jsou a Rooms
jsou instance tříd .NET. Tyto vlastnosti představují složitější datové struktury a v důsledku toho vyžadují pole se složitým datovým typem v indexu.
Vlastnost Address
představuje sadu více hodnot ve Address
třídě definované níže:
using System;
using Microsoft.Azure.Search;
using Microsoft.Azure.Search.Models;
using Newtonsoft.Json;
namespace AzureSearch.SDKHowTo
{
public partial class Address
{
[IsSearchable]
public string StreetAddress { get; set; }
[IsSearchable, IsFilterable, IsSortable, IsFacetable]
public string City { get; set; }
[IsSearchable, IsFilterable, IsSortable, IsFacetable]
public string StateProvince { get; set; }
[IsSearchable, IsFilterable, IsSortable, IsFacetable]
public string PostalCode { get; set; }
[IsSearchable, IsFilterable, IsSortable, IsFacetable]
public string Country { get; set; }
}
}
Tato třída obsahuje standardní hodnoty používané k popisu adres v USA nebo Kanadě. K seskupení logických polí v indexu můžete použít podobné typy.
Vlastnost Rooms
představuje pole Room
objektů:
using System;
using Microsoft.Azure.Search;
using Microsoft.Azure.Search.Models;
using Newtonsoft.Json;
namespace AzureSearch.SDKHowTo
{
public partial class Room
{
[IsSearchable]
[Analyzer(AnalyzerName.AsString.EnMicrosoft)]
public string Description { get; set; }
[IsSearchable]
[Analyzer(AnalyzerName.AsString.FrMicrosoft)]
[JsonProperty("Description_fr")]
public string DescriptionFr { get; set; }
[IsSearchable, IsFilterable, IsFacetable]
public string Type { get; set; }
[IsFilterable, IsFacetable]
public double? BaseRate { get; set; }
[IsSearchable, IsFilterable, IsFacetable]
public string BedOptions { get; set; }
[IsFilterable, IsFacetable]
public int SleepsCount { get; set; }
[IsFilterable, IsFacetable]
public bool? SmokingAllowed { get; set; }
[IsSearchable, IsFilterable, IsFacetable]
public string[] Tags { get; set; }
}
}
Datový model v .NET a jeho odpovídající schéma indexu by mělo být navržené tak, aby podporovalo vyhledávací prostředí, které chcete koncovému uživateli poskytnout. Každý objekt nejvyšší úrovně v .NET, tj. dokument v indexu, odpovídá výsledku hledání, který byste představili ve svém uživatelském rozhraní. Například v aplikaci pro vyhledávání hotelů mohou koncoví uživatelé chtít hledat podle názvu hotelu, funkcí hotelu nebo vlastností konkrétní místnosti. O něco později se podíváme na některé příklady dotazů.
Tato schopnost používat vlastní třídy k interakci s dokumenty v indexu funguje v obou směrech; Můžete také načíst výsledky hledání a mít sadu SDK automaticky deserializovat na typ vašeho výběru, jak uvidíme v další části.
Poznámka
Sada Azure Cognitive Search .NET SDK také podporuje dynamicky napsané dokumenty pomocí Document
třídy, což je mapování názvů polí na hodnoty polí klíč/hodnota. To je užitečné v situacích, kdy v době navrhování neznáte schéma indexu nebo kde by vázání na konkrétní třídy modelu bylo nepraktické. Všechny metody v sadě SDK, které pracují s dokumenty, mají přetížení, které pracují se třídou Document
, ale i přetížení silně závislá na typu, která přebírají parametr obecného typu. V ukázkovém kódu v tomto kurzu se používají pouze ty druhé.
TřídaDocument
dědí z Dictionary<string, object>
.
Proč byste měli používat datové typy s možnou hodnotou null
Při návrhu vlastních tříd modelu pro mapování na index Azure Cognitive Search doporučujeme deklarovat vlastnosti typů hodnot, jako bool
je hodnota int
null (například bool?
místo bool
). Pokud použijete vlastnost se zakázanou hodnotou null, musíte zajistit, aby žádné dokumenty v indexu neobsahovaly pro odpovídající pole hodnotu null. Ani sada SDK ani služba Azure Cognitive Search vám to nepomůže vynutit.
Nejedná se pouze o hypotetický problém: představte si situaci, kdy přidáte nové pole do stávajícího indexu 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í hodnotu null v Azure Cognitive Search). Pokud pak použijete třídu modelu s vlastností int
se zakázanou hodnotou null, při pokusu o načtení dokumentů dojde k vyvolání podobné výjimky JsonSerializationException
:
Error converting value {null} to type 'System.Int32'. Path 'IntValue'.
Z tohoto důvodu doporučujeme jako osvědčený postup používat ve třídách modelu typy s možnou hodnotou null.
Vlastní serializace pomocí JSON.NET
Sada SDK používá JSON.NET pro serializaci a deserializaci dokumentů. Serializace a deserializace můžete přizpůsobit v případě potřeby definováním vlastního nebo JsonConverter
IContractResolver
. Další informace najdete v dokumentaci k JSON.NET. To může být užitečné, když chcete přizpůsobit existující třídu modelu z aplikace pro použití s Azure Cognitive Search a další pokročilejší scénáře. Například s vlastní serializací můžete:
- Zahrňte nebo vylučte určité vlastnosti třídy modelu, aby se uložily jako pole dokumentu.
- Mapujte mezi názvy vlastností v kódu a názvy polí v indexu.
- Vytvořte vlastní atributy, které lze použít k mapování vlastností na pole dokumentu.
Příklady implementace vlastní serializace najdete v testech jednotek pro sadu Azure Cognitive Search .NET SDK na GitHub. Dobrým výchozím bodem je tato složka. Obsahuje třídy používané vlastními serializačními testy.
Hledání dokumentů v indexu
Posledním krokem ukázkové aplikace je vyhledání některých dokumentů v indexu:
private static void RunQueries(ISearchIndexClient indexClient)
{
SearchParameters parameters;
DocumentSearchResult<Hotel> results;
Console.WriteLine("Search the entire index for the term 'motel' and return only the HotelName field:\n");
parameters =
new SearchParameters()
{
Select = new[] { "HotelName" }
};
results = indexClient.Documents.Search<Hotel>("motel", parameters);
WriteDocuments(results);
Console.Write("Apply a filter to the index to find hotels with a room cheaper than $100 per night, ");
Console.WriteLine("and return the hotelId and description:\n");
parameters =
new SearchParameters()
{
Filter = "Rooms/any(r: r/BaseRate lt 100)",
Select = new[] { "HotelId", "Description" }
};
results = indexClient.Documents.Search<Hotel>("*", parameters);
WriteDocuments(results);
Console.Write("Search the entire index, order by a specific field (lastRenovationDate) ");
Console.Write("in descending order, take the top two results, and show only hotelName and ");
Console.WriteLine("lastRenovationDate:\n");
parameters =
new SearchParameters()
{
OrderBy = new[] { "LastRenovationDate desc" },
Select = new[] { "HotelName", "LastRenovationDate" },
Top = 2
};
results = indexClient.Documents.Search<Hotel>("*", parameters);
WriteDocuments(results);
Console.WriteLine("Search the entire index for the term 'hotel':\n");
parameters = new SearchParameters();
results = indexClient.Documents.Search<Hotel>("hotel", parameters);
WriteDocuments(results);
}
Pokaždé, když spustí dotaz, tato metoda nejprve vytvoří nový SearchParameters
objekt. Tento objekt slouží k určení dalších možností dotazu, jako je řazení, filtrování, stránkování a omezující vlastnosti. V této metodě nastavujeme vlastnost Filter
, , Select
OrderBy
a Top
vlastnost pro různé dotazy.
SearchParameters
Všechny vlastnosti jsou zde popsané.
Dalším krokem je skutečné spuštění vyhledávacího dotazu. Spuštění hledání se provádí pomocí Documents.Search
metody. Pro každý dotaz předáme hledaný text, který se použije jako řetězec (nebo "*"
pokud neexistuje žádný hledaný text), plus parametry hledání vytvořené dříve. Také jsme zadali Hotel
jako parametr Documents.Search
typu , který sadě SDK říká deserializaci dokumentů ve výsledcích hledání na objekty typu Hotel
.
Poznámka
Další informace o syntaxi výrazu vyhledávacího dotazu najdete tady.
Nakonec po každém dotazu tato metoda iteruje všechny shody ve výsledcích hledání a vytiskne každý dokument do konzoly:
private static void WriteDocuments(DocumentSearchResult<Hotel> searchResults)
{
foreach (SearchResult<Hotel> result in searchResults.Results)
{
Console.WriteLine(result.Document);
}
Console.WriteLine();
}
Pojďme se podrobněji podívat na jednotlivé dotazy. Tady je kód pro spuštění prvního dotazu:
parameters =
new SearchParameters()
{
Select = new[] { "HotelName" }
};
results = indexClient.Documents.Search<Hotel>("motel", parameters);
WriteDocuments(results);
V tomto případě prohledáme celé indexy slovo "motel" v libovolném prohledávatelném poli a chceme načíst pouze názvy hotelů, jak je uvedeno parametrem Select
. Tady jsou výsledky:
Name: Secret Point Motel
Name: Twin Dome Motel
Další dotaz je trochu zajímavější. Chceme najít všechny hotely, které mají pokoj s noční sazbou nižší než 100 USD, a vrátit pouze ID hotelu a popis:
parameters =
new SearchParameters()
{
Filter = "Rooms/any(r: r/BaseRate lt 100)",
Select = new[] { "HotelId", "Description" }
};
results = indexClient.Documents.Search<Hotel>("*", parameters);
WriteDocuments(results);
Tento dotaz používá k filtrování dokumentů v indexu výraz Rooms/any(r: r/BaseRate lt 100)
OData$filter
. Tento operátor použije všechny operátory k použití BaseRate lt 100 pro každou položku v kolekci Rooms. Další informace o syntaxi OData, která Azure Cognitive Search podporuje, najdete tady.
Tady jsou výsledky dotazu:
HotelId: 1
Description: The hotel is ideally located on the main commercial artery of the city in the heart of New York...
HotelId: 2
Description: The hotel is situated in a nineteenth century plaza, which has been expanded and renovated to...
Dále chceme najít nejlepší dva hotely, které byly nedávno renovovány, a ukázat název hotelu a datum poslední renovace. Zde je kód:
parameters =
new SearchParameters()
{
OrderBy = new[] { "LastRenovationDate desc" },
Select = new[] { "HotelName", "LastRenovationDate" },
Top = 2
};
results = indexClient.Documents.Search<Hotel>("*", parameters);
WriteDocuments(results);
V tomto případě znovu použijeme syntaxi OData k určení parametru OrderBy
jako lastRenovationDate desc
. Také jsme nastavili Top
hodnotu 2, abychom zajistili, že získáme jenom první dva dokumenty. Stejně jako předtím nastavíme, abychom určili Select
, která pole se mají vrátit.
Tady jsou výsledky:
Name: Fancy Stay Last renovated on: 6/27/2010 12:00:00 AM +00:00
Name: Roach Motel Last renovated on: 4/28/1982 12:00:00 AM +00:00
Nakonec chceme najít všechny názvy hotelů, které odpovídají slovu "hotel":
parameters = new SearchParameters()
{
SearchFields = new[] { "HotelName" }
};
results = indexClient.Documents.Search<Hotel>("hotel", parameters);
WriteDocuments(results);
A tady jsou výsledky, které zahrnují všechna pole, protože jsme nezadali Select
vlastnost:
HotelId: 3
Name: Triple Landscape Hotel
...
Tento krok dokončí kurz, ale nezastavujte se tady. **Další kroky poskytují další zdroje informací o Azure Cognitive Search.
Další kroky
- Projděte si referenční materiály pro .NET SDK a REST API.
- Projděte si zásady vytváření názvů a seznamte se s pravidly pro pojmenování různých objektů.
- Projděte si podporované datové typy v Azure Cognitive Search.