Rövid útmutató: Teljes szöveges keresés az Azure SDK-k használatával
Megtudhatja, hogyan hozhat létre, tölthet be és kérdezhet le keresési indexet az Azure.Search.Documents ügyféloldali kódtár használatával a teljes szöveges keresés mintaadataival. A teljes szöveges keresés az Apache Lucene-t használja az indexeléshez és a lekérdezésekhez, valamint egy BM25 rangsorolási algoritmust a pontozási eredményekhez.
Ez a rövid útmutató létrehoz és lekérdez egy kisméretű, négy szállodára vonatkozó adatokat tartalmazó rövid útmutató-indexet.
Tipp.
Letöltheti a forráskódot, hogy befejezett projekttel kezdjen, vagy kövesse az alábbi lépéseket a saját létrehozásához.
Előfeltételek
- Aktív Azure-előfizetés – Ingyenes létrehozás
- Azure AI-Search szolgáltatás. Ha nincs ilyen szolgáltatása, hozzon létre egy szolgáltatást . Ehhez a rövid útmutatóhoz ingyenes szintet használhat.
A Microsoft Entra ID előfeltételei
A Microsoft Entra-azonosítóval javasolt kulcs nélküli hitelesítéshez a következőket kell elvégeznie:
- Telepítse a Kulcs nélküli hitelesítéshez használt Azure CLI-t a Microsoft Entra-azonosítóval.
- Rendelje hozzá mindkét
Search Service Contributor
Search Index Data Contributor
szerepkört a felhasználói fiókjához. Szerepköröket az Azure Portalon rendelhet hozzá a Hozzáférés-vezérlés (IAM)>Szerepkör-hozzárendelés hozzáadása területen. További információ: Csatlakozás az Azure AI Searchhez szerepkörök használatával.
Erőforrásadatok lekérése
Az alkalmazás Azure AI-Search szolgáltatás történő hitelesítéséhez le kell kérnie a következő adatokat:
Változó neve | Érték |
---|---|
SEARCH_API_ENDPOINT |
Ez az érték az Azure Portalon található. Válassza ki a keresési szolgáltatást, majd a bal oldali menüben válassza az Áttekintés lehetőséget. Az Essentials alatt található URL-érték a szükséges végpont. A végpontok például a következőképpen nézhetnek ki: https://mydemo.search.windows.net . |
További információ a kulcs nélküli hitelesítésről és a környezeti változók beállításáról.
Beállítás
Hozzon létre egy új mappát
full-text-quickstart
, amely tartalmazza az alkalmazást, és nyissa meg a Visual Studio Code-ot abban a mappában a következő paranccsal:mkdir full-text-quickstart && cd full-text-quickstart
Hozzon létre egy új konzolalkalmazást a következő paranccsal:
dotnet new console
Telepítse az Azure AI Search ügyfélkódtárát (Azure.Search.Documents) a .NET-hez a következőkkel:
dotnet add package Azure.Search.Documents
A Microsoft Entra ID-val javasolt kulcs nélküli hitelesítéshez telepítse az Azure.Identity csomagot a következőkkel:
dotnet add package Azure.Identity
A Microsoft Entra ID-val javasolt kulcs nélküli hitelesítéshez jelentkezzen be az Azure-ba a következő paranccsal:
az login
Keresési index létrehozása, betöltése és lekérdezése
Az előző beállítási szakaszban létrehozott egy új konzolalkalmazást, és telepítette az Azure AI Search ügyfélkódtárát.
Ebben a szakaszban kódot ad hozzá egy keresési index létrehozásához, dokumentumokkal való betöltéséhez és lekérdezések futtatásához. Futtassa a programot az eredmények megtekintéséhez a konzolon. A kód részletes magyarázatát a kódszakaszban találja.
A rövid útmutatóban szereplő mintakód a Microsoft Entra-azonosítót használja az ajánlott kulcs nélküli hitelesítéshez. Ha inkább API-kulcsot szeretne használni, lecserélheti az DefaultAzureCredential
objektumot egy objektumra AzureKeyCredential
.
Uri serviceEndpoint = new Uri($"https://<Put your search service NAME here>.search.windows.net/");
DefaultAzureCredential credential = new();
A Program.cs illessze be a következő kódot. Szerkessze a
serviceName
keresési szolgáltatás nevét ésapiKey
a rendszergazdai API-kulcsot tartalmazó változókat.using System; using Azure; using Azure.Identity; using Azure.Search.Documents; using Azure.Search.Documents.Indexes; using Azure.Search.Documents.Indexes.Models; using Azure.Search.Documents.Models; namespace AzureSearch.Quickstart { class Program { static void Main(string[] args) { // Your search service endpoint Uri serviceEndpoint = new Uri($"https://<Put your search service NAME here>.search.windows.net/"); // Use the recommended keyless credential instead of the AzureKeyCredential credential. DefaultAzureCredential credential = new(); //AzureKeyCredential credential = new AzureKeyCredential("Your search service admin key"); // Create a SearchIndexClient to send create/delete index commands SearchIndexClient searchIndexClient = new SearchIndexClient(serviceEndpoint, credential); // Create a SearchClient to load and query documents string indexName = "hotels-quickstart"; SearchClient searchClient = new SearchClient(serviceEndpoint, indexName, credential); // Delete index if it exists Console.WriteLine("{0}", "Deleting index...\n"); DeleteIndexIfExists(indexName, searchIndexClient); // Create index Console.WriteLine("{0}", "Creating index...\n"); CreateIndex(indexName, searchIndexClient); SearchClient ingesterClient = searchIndexClient.GetSearchClient(indexName); // Load documents Console.WriteLine("{0}", "Uploading documents...\n"); UploadDocuments(ingesterClient); // Wait 2 secondsfor indexing to complete before starting queries (for demo and console-app purposes only) Console.WriteLine("Waiting for indexing...\n"); System.Threading.Thread.Sleep(2000); // Call the RunQueries method to invoke a series of queries Console.WriteLine("Starting queries...\n"); RunQueries(searchClient); // End the program Console.WriteLine("{0}", "Complete. Press any key to end this program...\n"); Console.ReadKey(); } // Delete the hotels-quickstart index to reuse its name private static void DeleteIndexIfExists(string indexName, SearchIndexClient searchIndexClient) { searchIndexClient.GetIndexNames(); { searchIndexClient.DeleteIndex(indexName); } } // Create hotels-quickstart index private static void CreateIndex(string indexName, SearchIndexClient searchIndexClient) { FieldBuilder fieldBuilder = new FieldBuilder(); var searchFields = fieldBuilder.Build(typeof(Hotel)); var definition = new SearchIndex(indexName, searchFields); var suggester = new SearchSuggester("sg", new[] { "HotelName", "Category", "Address/City", "Address/StateProvince" }); definition.Suggesters.Add(suggester); searchIndexClient.CreateOrUpdateIndex(definition); } // Upload documents in a single Upload request. private static void UploadDocuments(SearchClient searchClient) { IndexDocumentsBatch<Hotel> batch = IndexDocumentsBatch.Create( IndexDocumentsAction.Upload( new Hotel() { HotelId = "1", HotelName = "Secret Point Motel", 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 Time's 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.", DescriptionFr = "L'hôtel est idéalement situé sur la principale artère commerciale de la ville en plein cœur de New York. A quelques minutes se trouve la place du temps et le centre historique de la ville, ainsi que d'autres lieux d'intérêt qui font de New York l'une des villes les plus attractives et cosmopolites de l'Amérique.", Category = "Boutique", Tags = new[] { "pool", "air conditioning", "concierge" }, ParkingIncluded = false, LastRenovationDate = new DateTimeOffset(1970, 1, 18, 0, 0, 0, TimeSpan.Zero), Rating = 3.6, Address = new Address() { StreetAddress = "677 5th Ave", City = "New York", StateProvince = "NY", PostalCode = "10022", Country = "USA" } }), IndexDocumentsAction.Upload( new Hotel() { HotelId = "2", HotelName = "Twin Dome Motel", 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.", DescriptionFr = "L'hôtel est situé dans une place du XIXe siècle, qui a été agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel moderne, fonctionnel et de première classe dans lequel l'art et les éléments historiques uniques coexistent avec le confort le plus moderne.", Category = "Boutique", Tags = new[] { "pool", "free wifi", "concierge" }, ParkingIncluded = false, LastRenovationDate = new DateTimeOffset(1979, 2, 18, 0, 0, 0, TimeSpan.Zero), Rating = 3.60, Address = new Address() { StreetAddress = "140 University Town Center Dr", City = "Sarasota", StateProvince = "FL", PostalCode = "34243", Country = "USA" } }), IndexDocumentsAction.Upload( new Hotel() { HotelId = "3", HotelName = "Triple Landscape Hotel", Description = "The Hotel stands out for its gastronomic excellence under the management of William Dough, who advises on and oversees all of the Hotel’s restaurant services.", DescriptionFr = "L'hôtel est situé dans une place du XIXe siècle, qui a été agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel moderne, fonctionnel et de première classe dans lequel l'art et les éléments historiques uniques coexistent avec le confort le plus moderne.", Category = "Resort and Spa", Tags = new[] { "air conditioning", "bar", "continental breakfast" }, ParkingIncluded = true, LastRenovationDate = new DateTimeOffset(2015, 9, 20, 0, 0, 0, TimeSpan.Zero), Rating = 4.80, Address = new Address() { StreetAddress = "3393 Peachtree Rd", City = "Atlanta", StateProvince = "GA", PostalCode = "30326", Country = "USA" } }), IndexDocumentsAction.Upload( new Hotel() { HotelId = "4", HotelName = "Sublime Cliff Hotel", Description = "Sublime Cliff Hotel is located in the heart of the historic center of Sublime in an extremely vibrant and lively area within short walking distance to the sites and landmarks of the city and is surrounded by the extraordinary beauty of churches, buildings, shops and monuments. Sublime Cliff is part of a lovingly restored 1800 palace.", DescriptionFr = "Le sublime Cliff Hotel est situé au coeur du centre historique de sublime dans un quartier extrêmement animé et vivant, à courte distance de marche des sites et monuments de la ville et est entouré par l'extraordinaire beauté des églises, des bâtiments, des commerces et Monuments. Sublime Cliff fait partie d'un Palace 1800 restauré avec amour.", Category = "Boutique", Tags = new[] { "concierge", "view", "24-hour front desk service" }, ParkingIncluded = true, LastRenovationDate = new DateTimeOffset(1960, 2, 06, 0, 0, 0, TimeSpan.Zero), Rating = 4.60, Address = new Address() { StreetAddress = "7400 San Pedro Ave", City = "San Antonio", StateProvince = "TX", PostalCode = "78216", Country = "USA" } }) ); try { IndexDocumentsResult result = searchClient.IndexDocuments(batch); } catch (Exception) { // If for some reason any documents are dropped during indexing, you can compensate by delaying and // retrying. This simple demo just logs the failed document keys and continues. Console.WriteLine("Failed to index some of the documents: {0}"); } } // Run queries, use WriteDocuments to print output private static void RunQueries(SearchClient searchClient) { SearchOptions options; SearchResults<Hotel> response; // Query 1 Console.WriteLine("Query #1: Search on empty term '*' to return all documents, showing a subset of fields...\n"); options = new SearchOptions() { IncludeTotalCount = true, Filter = "", OrderBy = { "" } }; options.Select.Add("HotelId"); options.Select.Add("HotelName"); options.Select.Add("Rating"); response = searchClient.Search<Hotel>("*", options); WriteDocuments(response); // Query 2 Console.WriteLine("Query #2: Search on 'hotels', filter on 'Rating gt 4', sort by Rating in descending order...\n"); options = new SearchOptions() { Filter = "Rating gt 4", OrderBy = { "Rating desc" } }; options.Select.Add("HotelId"); options.Select.Add("HotelName"); options.Select.Add("Rating"); response = searchClient.Search<Hotel>("hotels", options); WriteDocuments(response); // Query 3 Console.WriteLine("Query #3: Limit search to specific fields (pool in Tags field)...\n"); options = new SearchOptions() { SearchFields = { "Tags" } }; options.Select.Add("HotelId"); options.Select.Add("HotelName"); options.Select.Add("Tags"); response = searchClient.Search<Hotel>("pool", options); WriteDocuments(response); // Query 4 - Use Facets to return a faceted navigation structure for a given query // Filters are typically used with facets to narrow results on OnClick events Console.WriteLine("Query #4: Facet on 'Category'...\n"); options = new SearchOptions() { Filter = "" }; options.Facets.Add("Category"); options.Select.Add("HotelId"); options.Select.Add("HotelName"); options.Select.Add("Category"); response = searchClient.Search<Hotel>("*", options); WriteDocuments(response); // Query 5 Console.WriteLine("Query #5: Look up a specific document...\n"); Response<Hotel> lookupResponse; lookupResponse = searchClient.GetDocument<Hotel>("3"); Console.WriteLine(lookupResponse.Value.HotelId); // Query 6 Console.WriteLine("Query #6: Call Autocomplete on HotelName...\n"); var autoresponse = searchClient.Autocomplete("sa", "sg"); WriteDocuments(autoresponse); } // Write search results to console private static void WriteDocuments(SearchResults<Hotel> searchResults) { foreach (SearchResult<Hotel> result in searchResults.GetResults()) { Console.WriteLine(result.Document); } Console.WriteLine(); } private static void WriteDocuments(AutocompleteResults autoResults) { foreach (AutocompleteItem result in autoResults.Results) { Console.WriteLine(result.Text); } Console.WriteLine(); } } }
Ugyanabban a mappában hozzon létre egy Hotel.cs nevű új fájlt, és illessze be a következő kódot. Ez a kód egy szállodai dokumentum struktúráját határozza meg.
using System; using System.Text.Json.Serialization; using Azure.Search.Documents.Indexes; using Azure.Search.Documents.Indexes.Models; namespace AzureSearch.Quickstart { public partial class Hotel { [SimpleField(IsKey = true, IsFilterable = true)] public string HotelId { get; set; } [SearchableField(IsSortable = true)] public string HotelName { get; set; } [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.EnLucene)] public string Description { get; set; } [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.FrLucene)] [JsonPropertyName("Description_fr")] public string DescriptionFr { get; set; } [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)] public string Category { get; set; } [SearchableField(IsFilterable = true, IsFacetable = true)] public string[] Tags { get; set; } [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)] public bool? ParkingIncluded { get; set; } [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)] public DateTimeOffset? LastRenovationDate { get; set; } [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)] public double? Rating { get; set; } [SearchableField] public Address Address { get; set; } } }
Hozzon létre egy Hotel.cs nevű új fájlt, és illessze be a következő kódot egy szállodai dokumentum szerkezetének meghatározásához. A mező attribútumai határozzák meg, hogyan használják azt egy alkalmazásban. Az attribútumot például minden olyan mezőhöz hozzá kell rendelni,
IsFilterable
amely egy szűrőkifejezést támogat.using System; using System.Text.Json.Serialization; using Azure.Search.Documents.Indexes; using Azure.Search.Documents.Indexes.Models; namespace AzureSearch.Quickstart { public partial class Hotel { [SimpleField(IsKey = true, IsFilterable = true)] public string HotelId { get; set; } [SearchableField(IsSortable = true)] public string HotelName { get; set; } [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.EnLucene)] public string Description { get; set; } [SearchableField(AnalyzerName = LexicalAnalyzerName.Values.FrLucene)] [JsonPropertyName("Description_fr")] public string DescriptionFr { get; set; } [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)] public string Category { get; set; } [SearchableField(IsFilterable = true, IsFacetable = true)] public string[] Tags { get; set; } [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)] public bool? ParkingIncluded { get; set; } [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)] public DateTimeOffset? LastRenovationDate { get; set; } [SimpleField(IsFilterable = true, IsSortable = true, IsFacetable = true)] public double? Rating { get; set; } [SearchableField] public Address Address { get; set; } } }
Hozzon létre egy Address.cs nevű új fájlt, és illessze be a következő kódot egy címdokumentum szerkezetének meghatározásához.
using Azure.Search.Documents.Indexes; namespace AzureSearch.Quickstart { public partial class Address { [SearchableField(IsFilterable = true)] public string StreetAddress { get; set; } [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)] public string City { get; set; } [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)] public string StateProvince { get; set; } [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)] public string PostalCode { get; set; } [SearchableField(IsFilterable = true, IsSortable = true, IsFacetable = true)] public string Country { get; set; } } }
Hozzon létre egy Hotel.Methods.cs nevű új fájlt, és illessze be a következő kódot az osztály felülbírálásának
Hotel
meghatározásáhozToString()
.using System; using System.Text; namespace AzureSearch.Quickstart { public partial class Hotel { public override string ToString() { var builder = new StringBuilder(); if (!String.IsNullOrEmpty(HotelId)) { builder.AppendFormat("HotelId: {0}\n", HotelId); } if (!String.IsNullOrEmpty(HotelName)) { builder.AppendFormat("Name: {0}\n", HotelName); } if (!String.IsNullOrEmpty(Description)) { builder.AppendFormat("Description: {0}\n", Description); } if (!String.IsNullOrEmpty(DescriptionFr)) { builder.AppendFormat("Description (French): {0}\n", DescriptionFr); } if (!String.IsNullOrEmpty(Category)) { builder.AppendFormat("Category: {0}\n", Category); } if (Tags != null && Tags.Length > 0) { builder.AppendFormat("Tags: [ {0} ]\n", String.Join(", ", Tags)); } if (ParkingIncluded.HasValue) { builder.AppendFormat("Parking included: {0}\n", ParkingIncluded.Value ? "yes" : "no"); } if (LastRenovationDate.HasValue) { builder.AppendFormat("Last renovated on: {0}\n", LastRenovationDate); } if (Rating.HasValue) { builder.AppendFormat("Rating: {0}\n", Rating); } if (Address != null && !Address.IsEmpty) { builder.AppendFormat("Address: \n{0}\n", Address.ToString()); } return builder.ToString(); } } }
Hozzon létre egy Address.Methods.cs nevű új fájlt, és illessze be a következő kódot az osztály felülbírálásának
Address
definiálásáhozToString()
.using System; using System.Text; using System.Text.Json.Serialization; namespace AzureSearch.Quickstart { public partial class Address { public override string ToString() { var builder = new StringBuilder(); if (!IsEmpty) { builder.AppendFormat("{0}\n{1}, {2} {3}\n{4}", StreetAddress, City, StateProvince, PostalCode, Country); } return builder.ToString(); } [JsonIgnore] public bool IsEmpty => String.IsNullOrEmpty(StreetAddress) && String.IsNullOrEmpty(City) && String.IsNullOrEmpty(StateProvince) && String.IsNullOrEmpty(PostalCode) && String.IsNullOrEmpty(Country); } }
Hozza létre és futtassa az alkalmazást a következő paranccsal:
dotnet run
A kimenet tartalmazza a Console.WriteLine üzeneteit, a lekérdezési információk és eredmények hozzáadásával.
A kód ismertetése
Az előző szakaszokban létrehozott egy új konzolalkalmazást, és telepítette az Azure AI Search ügyfélkódtárát. Hozzáadta a kódot egy keresési index létrehozásához, a dokumentumokba való betöltéséhez és a lekérdezések futtatásához. Futtatta a programot az eredmények megtekintéséhez a konzolon.
Ebben a szakaszban bemutatjuk a konzolalkalmazáshoz hozzáadott kódot.
Keresési ügyfél létrehozása
A Program.cs két ügyfelet hozott létre:
- A SearchIndexClient létrehozza az indexet.
- A SearchClient betölt és lekérdez egy meglévő indexet.
Mindkét ügyfélnek szüksége van a keresési szolgáltatásvégpontra és az erőforrás-információk szakaszban korábban ismertetett hitelesítő adatokra .
A rövid útmutatóban szereplő mintakód a Microsoft Entra-azonosítót használja az ajánlott kulcs nélküli hitelesítéshez. Ha inkább API-kulcsot szeretne használni, lecserélheti az DefaultAzureCredential
objektumot egy objektumra AzureKeyCredential
.
Uri serviceEndpoint = new Uri($"https://<Put your search service NAME here>.search.windows.net/");
DefaultAzureCredential credential = new();
static void Main(string[] args)
{
// Your search service endpoint
Uri serviceEndpoint = new Uri($"https://<Put your search service NAME here>.search.windows.net/");
// Use the recommended keyless credential instead of the AzureKeyCredential credential.
DefaultAzureCredential credential = new();
//AzureKeyCredential credential = new AzureKeyCredential("Your search service admin key");
// Create a SearchIndexClient to send create/delete index commands
SearchIndexClient searchIndexClient = new SearchIndexClient(serviceEndpoint, credential);
// Create a SearchClient to load and query documents
string indexName = "hotels-quickstart";
SearchClient searchClient = new SearchClient(serviceEndpoint, indexName, credential);
// REDACTED FOR BREVITY . . .
}
Index létrehozása
Ez a rövid útmutató létrehoz egy hotelindexet, amelyet a szálloda adataival tölt be, és lekérdezéseket hajt végre. Ebben a lépésben definiálja az index mezőit. Minden meződefiníció tartalmaz egy nevet, adattípust és attribútumot, amely meghatározza a mező használatát.
Ebben a példában az Azure.Search.Documents kódtár szinkron metódusait használjuk az egyszerűség és az olvashatóság érdekében. Éles forgatókönyvek esetén azonban aszinkron módszereket kell használnia az alkalmazás skálázható és rugalmas állapotának megőrzéséhez. Például a CreateIndexAsyncet használná a CreateIndex helyett.
A struktúrák meghatározása
Létrehozott két segédosztályt, Hotel.cs és Address.cs egy szállodai dokumentum struktúrájának és címének meghatározásához. Az Hotel
osztály tartalmazza a szállodaazonosító, a név, a leírás, a kategória, a címkék, a parkolás, a felújítás dátuma, az értékelés és a cím mezőit. Az Address
osztály tartalmazza a cím, a város, az állam/tartomány, az irányítószám és az ország/régió mezőit.
Az Azure.Search.Documents ügyfélkódtárban a SearchableField és a SimpleField használatával egyszerűsítheti a meződefiníciókat. Mindkettő a SearchField származéka, és potenciálisan egyszerűsítheti a kódot:
SimpleField
bármilyen adattípus lehet, mindig nem kereshető (teljes szöveges keresési lekérdezések esetén figyelmen kívül hagyva), és lekérdezhető (nem rejtett). Más attribútumok alapértelmezés szerint ki vannak kapcsolva, de engedélyezhetők. HasználhatSimpleField
dokumentumazonosítókat vagy mezőket, amelyeket csak szűrőkben, aspektusokban vagy pontozási profilokban használ. Ha igen, mindenképpen alkalmazza a forgatókönyvhöz szükséges attribútumokat, példáulIsKey = true
egy dokumentumazonosítót. További információ: SimpleFieldAttribute.cs a forráskódban.SearchableField
sztringnek kell lennie, és mindig kereshető és lekérdezhető. Más attribútumok alapértelmezés szerint ki vannak kapcsolva, de engedélyezhetők. Mivel ez a mezőtípus kereshető, támogatja a szinonimákat és az elemző tulajdonságainak teljes kiegészítését. További információ: SearchableFieldAttribute.cs a forráskódban.
Akár az alapszintű SearchField
API-t, akár az egyik segédmodellt használja, explicit módon engedélyeznie kell a szűrési, aspektus- és rendezési attribútumokat. Az IsFilterable, az IsSortable és az IsFacetable attribútumot például explicit módon kell hozzárendelni az előző mintában látható módon.
Keresési index létrehozása
A Program.cs létrehoz egy SearchIndex-objektumot , majd meghívja a CreateIndex metódust az index kifejezéséhez a keresési szolgáltatásban. Az index tartalmaz egy SearchSuggestert is, amely engedélyezi az automatikus kiegészítést a megadott mezőkön.
// Create hotels-quickstart index
private static void CreateIndex(string indexName, SearchIndexClient searchIndexClient)
{
FieldBuilder fieldBuilder = new FieldBuilder();
var searchFields = fieldBuilder.Build(typeof(Hotel));
var definition = new SearchIndex(indexName, searchFields);
var suggester = new SearchSuggester("sg", new[] { "HotelName", "Category", "Address/City", "Address/StateProvince" });
definition.Suggesters.Add(suggester);
searchIndexClient.CreateOrUpdateIndex(definition);
}
Dokumentumok betöltése
Az Azure AI Search a szolgáltatásban tárolt tartalmakon keres. Ebben a lépésben olyan JSON-dokumentumokat tölt be, amelyek megfelelnek a létrehozott szállodaindexnek.
Az Azure AI Searchben a keresési dokumentumok olyan adatstruktúrák, amelyek egyaránt bemenetek az indexeléshez és a lekérdezésekből származó kimenetekhez. A külső adatforrásból származó dokumentumbemenetek lehetnek egy adatbázis sorai, blobok a Blob Storage-ban vagy a lemezen lévő JSON-dokumentumok. Ebben a példában egy parancsikont hozunk létre, és négy szállodához ágyazunk be JSON-dokumentumokat magában a kódban.
Dokumentumok feltöltésekor IndexDocumentsBatch objektumot kell használnia. Az IndexDocumentsBatch
objektumok műveletek gyűjteményét tartalmazzák, amelyek mindegyike tartalmaz egy dokumentumot és egy tulajdonságot, amely közli az Azure AI Search szolgáltatással, hogy milyen műveletet kell végrehajtania (feltöltés, egyesítés, törlés és mergeOrUpload).
A Program.cs egy dokumentum- és indexműveleteket tartalmazó tömböt hoz létre, majd átadja a tömböt.IndexDocumentsBatch
Az alábbi dokumentumok megfelelnek a szállodai osztály által meghatározott, a hotels-quickstart indexnek.
// Upload documents in a single Upload request.
private static void UploadDocuments(SearchClient searchClient)
{
IndexDocumentsBatch<Hotel> batch = IndexDocumentsBatch.Create(
IndexDocumentsAction.Upload(
new Hotel()
{
HotelId = "1",
HotelName = "Stay-Kay City Hotel",
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 Time's 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.",
DescriptionFr = "L'hôtel est idéalement situé sur la principale artère commerciale de la ville en plein cœur de New York. A quelques minutes se trouve la place du temps et le centre historique de la ville, ainsi que d'autres lieux d'intérêt qui font de New York l'une des villes les plus attractives et cosmopolites de l'Amérique.",
Category = "Boutique",
Tags = new[] { "pool", "air conditioning", "concierge" },
ParkingIncluded = false,
LastRenovationDate = new DateTimeOffset(1970, 1, 18, 0, 0, 0, TimeSpan.Zero),
Rating = 3.6,
Address = new Address()
{
StreetAddress = "677 5th Ave",
City = "New York",
StateProvince = "NY",
PostalCode = "10022",
Country = "USA"
}
}),
// REDACTED FOR BREVITY
}
Az IndexDocumentsBatch objektum inicializálása után elküldheti azt az indexbe a SearchClient objektum IndexDocuments meghívásával.
A Dokumentumok betöltése a SearchClient Main()
használatával történik, de a művelethez rendszergazdai jogosultságok is szükségesek a szolgáltatáshoz, amely általában a SearchIndexClienthez van társítva. A művelet beállításának egyik módja a SearchClient beolvasása SearchIndexClient
(searchIndexClient
ebben a példában).
SearchClient ingesterClient = searchIndexClient.GetSearchClient(indexName);
// Load documents
Console.WriteLine("{0}", "Uploading documents...\n");
UploadDocuments(ingesterClient);
Mivel van egy konzolalkalmazásunk, amely az összes parancsot egymás után futtatja, 2 másodperces várakozási időt adunk hozzá az indexelés és a lekérdezések között.
// Wait 2 seconds for indexing to complete before starting queries (for demo and console-app purposes only)
Console.WriteLine("Waiting for indexing...\n");
System.Threading.Thread.Sleep(2000);
A 2 másodperces késleltetés kompenzálja az indexelést, amely aszinkron, így az összes dokumentum indexelhető a lekérdezések végrehajtása előtt. A késésben történő kódolás általában csak demókban, tesztekben és mintaalkalmazásokban szükséges.
Keresés az indexekben
Az első dokumentum indexelése után azonnal lekérheti a lekérdezési eredményeket, de az index tényleges tesztelésének várnia kell, amíg az összes dokumentum indexel.
Ez a szakasz két funkciót ad hozzá: lekérdezési logikát és eredményeket. Lekérdezésekhez használja a Keresés metódust. Ez a metódus a keresési szöveget (a lekérdezési sztringet) és más beállításokat használja.
A SearchResults osztály az eredményeket jelöli.
A Program.cs a WriteDocuments
metódus a keresési eredményeket a konzolra nyomtatja.
// Write search results to console
private static void WriteDocuments(SearchResults<Hotel> searchResults)
{
foreach (SearchResult<Hotel> result in searchResults.GetResults())
{
Console.WriteLine(result.Document);
}
Console.WriteLine();
}
private static void WriteDocuments(AutocompleteResults autoResults)
{
foreach (AutocompleteItem result in autoResults.Results)
{
Console.WriteLine(result.Text);
}
Console.WriteLine();
}
1. lekérdezési példa
A RunQueries
metódus lekérdezéseket hajt végre, és eredményeket ad vissza. Az eredmények hotelobjektumok. Ez a minta a metódus aláírását és az első lekérdezést mutatja be. Ez a lekérdezés bemutatja azt a Select
paramétert, amely lehetővé teszi az eredmény megírását a dokumentum kijelölt mezőivel.
// Run queries, use WriteDocuments to print output
private static void RunQueries(SearchClient searchClient)
{
SearchOptions options;
SearchResults<Hotel> response;
// Query 1
Console.WriteLine("Query #1: Search on empty term '*' to return all documents, showing a subset of fields...\n");
options = new SearchOptions()
{
IncludeTotalCount = true,
Filter = "",
OrderBy = { "" }
};
options.Select.Add("HotelId");
options.Select.Add("HotelName");
options.Select.Add("Address/City");
response = searchClient.Search<Hotel>("*", options);
WriteDocuments(response);
// REDACTED FOR BREVITY
}
2. lekérdezési példa
A második lekérdezésben keressen rá egy kifejezésre, adjon hozzá egy szűrőt, amely kiválasztja a 4-nél nagyobb minősítést tartalmazó dokumentumokat, majd csökkenő sorrendben rendezi az értékelés szerint. A szűrő egy logikai kifejezés, amelyet egy index IsFilterable mezőinek alapján értékel ki a program. A szűrő lekérdezések tartalmazhatnak vagy kizárnak értékeket. Ezért nincs relevanciapont társítva egy szűrő lekérdezéshez.
// Query 2
Console.WriteLine("Query #2: Search on 'hotels', filter on 'Rating gt 4', sort by Rating in descending order...\n");
options = new SearchOptions()
{
Filter = "Rating gt 4",
OrderBy = { "Rating desc" }
};
options.Select.Add("HotelId");
options.Select.Add("HotelName");
options.Select.Add("Rating");
response = searchClient.Search<Hotel>("hotels", options);
WriteDocuments(response);
3. lekérdezési példa
A harmadik lekérdezés egy teljes szöveges keresési művelet adott mezőkre való hatókörét mutatja be searchFields
.
// Query 3
Console.WriteLine("Query #3: Limit search to specific fields (pool in Tags field)...\n");
options = new SearchOptions()
{
SearchFields = { "Tags" }
};
options.Select.Add("HotelId");
options.Select.Add("HotelName");
options.Select.Add("Tags");
response = searchClient.Search<Hotel>("pool", options);
WriteDocuments(response);
4. lekérdezési példa
A negyedik lekérdezés bemutatja facets
, hogy milyen strukturált navigációs szerkezetek hozhatók létre.
// Query 4
Console.WriteLine("Query #4: Facet on 'Category'...\n");
options = new SearchOptions()
{
Filter = ""
};
options.Facets.Add("Category");
options.Select.Add("HotelId");
options.Select.Add("HotelName");
options.Select.Add("Category");
response = searchClient.Search<Hotel>("*", options);
WriteDocuments(response);
5. lekérdezési példa
Az ötödik lekérdezésben adjon vissza egy adott dokumentumot. A dokumentumkeresés általában egy eredményhalmaz eseményére OnClick
adott válasz.
// Query 5
Console.WriteLine("Query #5: Look up a specific document...\n");
Response<Hotel> lookupResponse;
lookupResponse = searchClient.GetDocument<Hotel>("3");
Console.WriteLine(lookupResponse.Value.HotelId);
6. lekérdezési példa
Az utolsó lekérdezés az automatikus kiegészítés szintaxisát jeleníti meg, szimulálva az sa részleges felhasználói bemenetét, amely az indexben definiált javaslathoz társított forrásmezőkben két lehetséges egyezésre oldható fel.
// Query 6
Console.WriteLine("Query #6: Call Autocomplete on HotelName that starts with 'sa'...\n");
var autoresponse = searchClient.Autocomplete("sa", "sg");
WriteDocuments(autoresponse);
Lekérdezések összegzése
Az előző lekérdezések több módon is egyeztetik a kifejezéseket a lekérdezésekben: teljes szöveges keresés, szűrők és automatikus kiegészítés.
A teljes szöveges keresést és a szűrőket a SearchClient.Search metódussal hajtja végre. A keresési lekérdezések átadhatók a sztringbensearchText
, míg egy szűrőkifejezés átadható a SearchOptions osztály Szűrő tulajdonságában. Ha keresés nélkül szeretne szűrni, egyszerűen adja meg "*"
a searchText
Keresési módszer paraméterét. Ha szűrés nélkül szeretne keresni, hagyja meg a Filter
tulajdonságot, vagy egyáltalán ne adja át a példányt SearchOptions
.
Megtudhatja, hogyan hozhat létre, tölthet be és kérdezhet le keresési indexet az Azure.Search.Documents ügyféloldali kódtár használatával a teljes szöveges keresés mintaadataival. A teljes szöveges keresés az Apache Lucene-t használja az indexeléshez és a lekérdezésekhez, valamint egy BM25 rangsorolási algoritmust a pontozási eredményekhez.
Ez a rövid útmutató létrehoz és lekérdez egy kisméretű, négy szállodára vonatkozó adatokat tartalmazó rövid útmutató-indexet.
Tipp.
Letöltheti a forráskódot, hogy befejezett projekttel kezdjen, vagy kövesse az alábbi lépéseket a saját létrehozásához.
Előfeltételek
- Aktív Azure-előfizetés – Ingyenes létrehozás
- Azure AI-Search szolgáltatás. Ha nincs ilyen szolgáltatása, hozzon létre egy szolgáltatást . Ehhez a rövid útmutatóhoz ingyenes szintet használhat.
A Microsoft Entra ID előfeltételei
A Microsoft Entra-azonosítóval javasolt kulcs nélküli hitelesítéshez a következőket kell elvégeznie:
- Telepítse a Kulcs nélküli hitelesítéshez használt Azure CLI-t a Microsoft Entra-azonosítóval.
- Rendelje hozzá mindkét
Search Service Contributor
Search Index Data Contributor
szerepkört a felhasználói fiókjához. Szerepköröket az Azure Portalon rendelhet hozzá a Hozzáférés-vezérlés (IAM)>Szerepkör-hozzárendelés hozzáadása területen. További információ: Csatlakozás az Azure AI Searchhez szerepkörök használatával.
Erőforrásadatok lekérése
Az alkalmazás Azure AI-Search szolgáltatás történő hitelesítéséhez le kell kérnie a következő adatokat:
Változó neve | Érték |
---|---|
SEARCH_API_ENDPOINT |
Ez az érték az Azure Portalon található. Válassza ki a keresési szolgáltatást, majd a bal oldali menüben válassza az Áttekintés lehetőséget. Az Essentials alatt található URL-érték a szükséges végpont. A végpontok például a következőképpen nézhetnek ki: https://mydemo.search.windows.net . |
További információ a kulcs nélküli hitelesítésről és a környezeti változók beállításáról.
Beállítás
A rövid útmutatóban szereplő minta a Java-futtatókörnyezettel működik. Telepítsen egy Java-fejlesztőkészletet, például az Azul Zulu OpenJDK-t. Az OpenJDK Microsoft buildjének vagy az előnyben részesített JDK-nak is működnie kell.
Telepítse az Apache Maven-t. Ezután futtassa
mvn -v
a sikeres telepítés megerősítéséhez.Hozzon létre egy új
pom.xml
fájlt a projekt gyökerében, és másolja bele a következő kódot:<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>azure.search.sample</groupId> <artifactId>azuresearchquickstart</artifactId> <version>1.0.0-SNAPSHOT</version> <build> <sourceDirectory>src</sourceDirectory> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.7.0</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>com.azure</groupId> <artifactId>azure-search-documents</artifactId> <version>11.7.3</version> </dependency> <dependency> <groupId>com.azure</groupId> <artifactId>azure-core</artifactId> <version>1.53.0</version> </dependency> <dependency> <groupId>com.azure</groupId> <artifactId>azure-identity</artifactId> <version>1.15.1</version> </dependency> </dependencies> </project>
Telepítse a függőségeket, beleértve az Azure AI Search ügyféloldali kódtárát (Azure.Search.Documents) a Java és az Azure Identity java-ügyfélkódtárához a következőkkel:
mvn clean dependency:copy-dependencies
A Microsoft Entra ID-val javasolt kulcs nélküli hitelesítéshez jelentkezzen be az Azure-ba a következő paranccsal:
az login
Keresési index létrehozása, betöltése és lekérdezése
Az előző beállítási szakaszban telepítette az Azure AI Search ügyfélkódtárat és más függőségeket.
Ebben a szakaszban kódot ad hozzá egy keresési index létrehozásához, dokumentumokkal való betöltéséhez és lekérdezések futtatásához. Futtassa a programot az eredmények megtekintéséhez a konzolon. A kód részletes magyarázatát a kódszakaszban találja.
A rövid útmutatóban szereplő mintakód a Microsoft Entra-azonosítót használja az ajánlott kulcs nélküli hitelesítéshez. Ha inkább API-kulcsot szeretne használni, lecserélheti az DefaultAzureCredential
objektumot egy objektumra AzureKeyCredential
.
String searchServiceEndpoint = "https://<Put your search service NAME here>.search.windows.net/";
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build();
Hozzon létre egy App.java nevű új fájlt, és illessze be a következő kódot a App.java:
import java.util.Arrays; import java.util.ArrayList; import java.time.OffsetDateTime; import java.time.ZoneOffset; import java.time.LocalDateTime; import java.time.LocalDate; import java.time.LocalTime; import com.azure.core.util.Configuration; import com.azure.core.util.Context; import com.azure.identity.DefaultAzureCredential; import com.azure.identity.DefaultAzureCredentialBuilder; import com.azure.search.documents.SearchClient; import com.azure.search.documents.SearchClientBuilder; import com.azure.search.documents.indexes.SearchIndexClient; import com.azure.search.documents.indexes.SearchIndexClientBuilder; import com.azure.search.documents.indexes.models.IndexDocumentsBatch; import com.azure.search.documents.models.SearchOptions; import com.azure.search.documents.indexes.models.SearchIndex; import com.azure.search.documents.indexes.models.SearchSuggester; import com.azure.search.documents.util.AutocompletePagedIterable; import com.azure.search.documents.util.SearchPagedIterable; public class App { public static void main(String[] args) { // Your search service endpoint "https://<Put your search service NAME here>.search.windows.net/"; // Use the recommended keyless credential instead of the AzureKeyCredential credential. DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build(); //AzureKeyCredential credential = new AzureKeyCredential("<Your search service admin key>"); // Create a SearchIndexClient to send create/delete index commands SearchIndexClient searchIndexClient = new SearchIndexClientBuilder() .endpoint(searchServiceEndpoint) .credential(credential) .buildClient(); // Create a SearchClient to load and query documents String indexName = "hotels-quickstart-java"; SearchClient searchClient = new SearchClientBuilder() .endpoint(searchServiceEndpoint) .credential(credential) .indexName(indexName) .buildClient(); // Create Search Index for Hotel model searchIndexClient.createOrUpdateIndex( new SearchIndex(indexName, SearchIndexClient.buildSearchFields(Hotel.class, null)) .setSuggesters(new SearchSuggester("sg", Arrays.asList("HotelName")))); // Upload sample hotel documents to the Search Index uploadDocuments(searchClient); // Wait 2 seconds for indexing to complete before starting queries (for demo and console-app purposes only) System.out.println("Waiting for indexing...\n"); try { Thread.sleep(2000); } catch (InterruptedException e) { } // Call the RunQueries method to invoke a series of queries System.out.println("Starting queries...\n"); RunQueries(searchClient); // End the program System.out.println("Complete.\n"); } // Upload documents in a single Upload request. private static void uploadDocuments(SearchClient searchClient) { var hotelList = new ArrayList<Hotel>(); var hotel = new Hotel(); hotel.hotelId = "1"; hotel.hotelName = "Stay-Kay City Hotel"; hotel.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 Time's 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."; hotel.descriptionFr = "L'hôtel est idéalement situé sur la principale artère commerciale de la ville en plein cœur de New York. A quelques minutes se trouve la place du temps et le centre historique de la ville, ainsi que d'autres lieux d'intérêt qui font de New York l'une des villes les plus attractives et cosmopolites de l'Amérique."; hotel.category = "Boutique"; hotel.tags = new String[] { "pool", "air conditioning", "concierge" }; hotel.parkingIncluded = false; hotel.lastRenovationDate = OffsetDateTime.of(LocalDateTime.of(LocalDate.of(1970, 1, 18), LocalTime.of(0, 0)), ZoneOffset.UTC); hotel.rating = 3.6; hotel.address = new Address(); hotel.address.streetAddress = "677 5th Ave"; hotel.address.city = "New York"; hotel.address.stateProvince = "NY"; hotel.address.postalCode = "10022"; hotel.address.country = "USA"; hotelList.add(hotel); hotel = new Hotel(); hotel.hotelId = "2"; hotel.hotelName = "Old Century Hotel"; hotel.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."; hotel.descriptionFr = "L'hôtel est situé dans une place du XIXe siècle, qui a été agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel moderne, fonctionnel et de première classe dans lequel l'art et les éléments historiques uniques coexistent avec le confort le plus moderne."; hotel.category = "Boutique"; hotel.tags = new String[] { "pool", "free wifi", "concierge" }; hotel.parkingIncluded = false; hotel.lastRenovationDate = OffsetDateTime.of(LocalDateTime.of(LocalDate.of(1979, 2, 18), LocalTime.of(0, 0)), ZoneOffset.UTC); hotel.rating = 3.60; hotel.address = new Address(); hotel.address.streetAddress = "140 University Town Center Dr"; hotel.address.city = "Sarasota"; hotel.address.stateProvince = "FL"; hotel.address.postalCode = "34243"; hotel.address.country = "USA"; hotelList.add(hotel); hotel = new Hotel(); hotel.hotelId = "3"; hotel.hotelName = "Gastronomic Landscape Hotel"; hotel.description = "The Hotel stands out for its gastronomic excellence under the management of William Dough, who advises on and oversees all of the Hotel’s restaurant services."; hotel.descriptionFr = "L'hôtel est situé dans une place du XIXe siècle, qui a été agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel moderne, fonctionnel et de première classe dans lequel l'art et les éléments historiques uniques coexistent avec le confort le plus moderne."; hotel.category = "Resort and Spa"; hotel.tags = new String[] { "air conditioning", "bar", "continental breakfast" }; hotel.parkingIncluded = true; hotel.lastRenovationDate = OffsetDateTime.of(LocalDateTime.of(LocalDate.of(2015, 9, 20), LocalTime.of(0, 0)), ZoneOffset.UTC); hotel.rating = 4.80; hotel.address = new Address(); hotel.address.streetAddress = "3393 Peachtree Rd"; hotel.address.city = "Atlanta"; hotel.address.stateProvince = "GA"; hotel.address.postalCode = "30326"; hotel.address.country = "USA"; hotelList.add(hotel); hotel = new Hotel(); hotel.hotelId = "4"; hotel.hotelName = "Sublime Palace Hotel"; hotel.description = "Sublime Palace Hotel is located in the heart of the historic center of Sublime in an extremely vibrant and lively area within short walking distance to the sites and landmarks of the city and is surrounded by the extraordinary beauty of churches, buildings, shops and monuments. Sublime Palace is part of a lovingly restored 1800 palace."; hotel.descriptionFr = "Le Sublime Palace Hotel est situé au coeur du centre historique de sublime dans un quartier extrêmement animé et vivant, à courte distance de marche des sites et monuments de la ville et est entouré par l'extraordinaire beauté des églises, des bâtiments, des commerces et Monuments. Sublime Palace fait partie d'un Palace 1800 restauré avec amour."; hotel.category = "Boutique"; hotel.tags = new String[] { "concierge", "view", "24-hour front desk service" }; hotel.parkingIncluded = true; hotel.lastRenovationDate = OffsetDateTime.of(LocalDateTime.of(LocalDate.of(1960, 2, 06), LocalTime.of(0, 0)), ZoneOffset.UTC); hotel.rating = 4.60; hotel.address = new Address(); hotel.address.streetAddress = "7400 San Pedro Ave"; hotel.address.city = "San Antonio"; hotel.address.stateProvince = "TX"; hotel.address.postalCode = "78216"; hotel.address.country = "USA"; hotelList.add(hotel); var batch = new IndexDocumentsBatch<Hotel>(); batch.addMergeOrUploadActions(hotelList); try { searchClient.indexDocuments(batch); } catch (Exception e) { e.printStackTrace(); // If for some reason any documents are dropped during indexing, you can compensate by delaying and // retrying. This simple demo just logs failure and continues System.err.println("Failed to index some of the documents"); } } // Write search results to console private static void WriteSearchResults(SearchPagedIterable searchResults) { searchResults.iterator().forEachRemaining(result -> { Hotel hotel = result.getDocument(Hotel.class); System.out.println(hotel); }); System.out.println(); } // Write autocomplete results to console private static void WriteAutocompleteResults(AutocompletePagedIterable autocompleteResults) { autocompleteResults.iterator().forEachRemaining(result -> { String text = result.getText(); System.out.println(text); }); System.out.println(); } // Run queries, use WriteDocuments to print output private static void RunQueries(SearchClient searchClient) { // Query 1 System.out.println("Query #1: Search on empty term '*' to return all documents, showing a subset of fields...\n"); SearchOptions options = new SearchOptions(); options.setIncludeTotalCount(true); options.setFilter(""); options.setOrderBy(""); options.setSelect("HotelId", "HotelName", "Address/City"); WriteSearchResults(searchClient.search("*", options, Context.NONE)); // Query 2 System.out.println("Query #2: Search on 'hotels', filter on 'Rating gt 4', sort by Rating in descending order...\n"); options = new SearchOptions(); options.setFilter("Rating gt 4"); options.setOrderBy("Rating desc"); options.setSelect("HotelId", "HotelName", "Rating"); WriteSearchResults(searchClient.search("hotels", options, Context.NONE)); // Query 3 System.out.println("Query #3: Limit search to specific fields (pool in Tags field)...\n"); options = new SearchOptions(); options.setSearchFields("Tags"); options.setSelect("HotelId", "HotelName", "Tags"); WriteSearchResults(searchClient.search("pool", options, Context.NONE)); // Query 4 System.out.println("Query #4: Facet on 'Category'...\n"); options = new SearchOptions(); options.setFilter(""); options.setFacets("Category"); options.setSelect("HotelId", "HotelName", "Category"); WriteSearchResults(searchClient.search("*", options, Context.NONE)); // Query 5 System.out.println("Query #5: Look up a specific document...\n"); Hotel lookupResponse = searchClient.getDocument("3", Hotel.class); System.out.println(lookupResponse.hotelId); System.out.println(); // Query 6 System.out.println("Query #6: Call Autocomplete on HotelName that starts with 's'...\n"); WriteAutocompleteResults(searchClient.autocomplete("s", "sg")); } }
Hozzon létre egy Hotel.java nevű új fájlt, és illessze be a következő kódot a Hotel.java:
import com.azure.search.documents.indexes.SearchableField; import com.azure.search.documents.indexes.SimpleField; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.annotation.JsonInclude.Include; import java.time.OffsetDateTime; /** * Model class representing a hotel. */ @JsonInclude(Include.NON_NULL) public class Hotel { /** * Hotel ID */ @JsonProperty("HotelId") @SimpleField(isKey = true) public String hotelId; /** * Hotel name */ @JsonProperty("HotelName") @SearchableField(isSortable = true) public String hotelName; /** * Description */ @JsonProperty("Description") @SearchableField(analyzerName = "en.microsoft") public String description; /** * French description */ @JsonProperty("DescriptionFr") @SearchableField(analyzerName = "fr.lucene") public String descriptionFr; /** * Category */ @JsonProperty("Category") @SearchableField(isFilterable = true, isSortable = true, isFacetable = true) public String category; /** * Tags */ @JsonProperty("Tags") @SearchableField(isFilterable = true, isFacetable = true) public String[] tags; /** * Whether parking is included */ @JsonProperty("ParkingIncluded") @SimpleField(isFilterable = true, isSortable = true, isFacetable = true) public Boolean parkingIncluded; /** * Last renovation time */ @JsonProperty("LastRenovationDate") @SimpleField(isFilterable = true, isSortable = true, isFacetable = true) public OffsetDateTime lastRenovationDate; /** * Rating */ @JsonProperty("Rating") @SimpleField(isFilterable = true, isSortable = true, isFacetable = true) public Double rating; /** * Address */ @JsonProperty("Address") public Address address; @Override public String toString() { try { return new ObjectMapper().writeValueAsString(this); } catch (JsonProcessingException e) { e.printStackTrace(); return ""; } } }
Hozzon létre egy Address.java nevű új fájlt, és illessze be a következő kódot a Address.java:
import com.azure.search.documents.indexes.SearchableField; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonInclude.Include; /** * Model class representing an address. */ @JsonInclude(Include.NON_NULL) public class Address { /** * Street address */ @JsonProperty("StreetAddress") @SearchableField public String streetAddress; /** * City */ @JsonProperty("City") @SearchableField(isFilterable = true, isSortable = true, isFacetable = true) public String city; /** * State or province */ @JsonProperty("StateProvince") @SearchableField(isFilterable = true, isSortable = true, isFacetable = true) public String stateProvince; /** * Postal code */ @JsonProperty("PostalCode") @SearchableField(isFilterable = true, isSortable = true, isFacetable = true) public String postalCode; /** * Country */ @JsonProperty("Country") @SearchableField(isFilterable = true, isSortable = true, isFacetable = true) public String country; }
Futtassa az új konzolalkalmazást:
javac Address.java App.java Hotel.java -cp ".;target\dependency\*" java -cp ".;target\dependency\*" App
A kód ismertetése
Az előző szakaszokban létrehozott egy új konzolalkalmazást, és telepítette az Azure AI Search ügyfélkódtárát. Hozzáadta a kódot egy keresési index létrehozásához, a dokumentumokba való betöltéséhez és a lekérdezések futtatásához. Futtatta a programot az eredmények megtekintéséhez a konzolon.
Ebben a szakaszban bemutatjuk a konzolalkalmazáshoz hozzáadott kódot.
Keresési ügyfél létrehozása
A App.java két ügyfelet hozott létre:
- A SearchIndexClient létrehozza az indexet.
- A SearchClient betölt és lekérdez egy meglévő indexet.
Mindkét ügyfélnek szüksége van a keresési szolgáltatásvégpontra és az erőforrás-információk szakaszban korábban ismertetett hitelesítő adatokra.
A rövid útmutatóban szereplő mintakód a Microsoft Entra-azonosítót használja az ajánlott kulcs nélküli hitelesítéshez. Ha inkább API-kulcsot szeretne használni, lecserélheti az DefaultAzureCredential
objektumot egy objektumra AzureKeyCredential
.
String searchServiceEndpoint = "https://<Put your search service NAME here>.search.windows.net/";
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build();
public static void main(String[] args) {
// Your search service endpoint
String searchServiceEndpoint = "https://<Put your search service NAME here>.search.windows.net/";
// Use the recommended keyless credential instead of the AzureKeyCredential credential.
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build();
//AzureKeyCredential credential = new AzureKeyCredential("Your search service admin key");
// Create a SearchIndexClient to send create/delete index commands
SearchIndexClient searchIndexClient = new SearchIndexClientBuilder()
.endpoint(searchServiceEndpoint)
.credential(credential)
.buildClient();
// Create a SearchClient to load and query documents
String indexName = "hotels-quickstart-java";
SearchClient searchClient = new SearchClientBuilder()
.endpoint(searchServiceEndpoint)
.credential(credential)
.indexName(indexName)
.buildClient();
// Create Search Index for Hotel model
searchIndexClient.createOrUpdateIndex(
new SearchIndex(indexName, SearchIndexClient.buildSearchFields(Hotel.class, null))
.setSuggesters(new SearchSuggester("sg", Arrays.asList("HotelName"))));
// REDACTED FOR BREVITY . . .
}
Index létrehozása
Ez a rövid útmutató létrehoz egy hotelindexet, amelyet a szálloda adataival tölt be, és lekérdezéseket hajt végre. Ebben a lépésben definiálja az index mezőit. Minden meződefiníció tartalmaz egy nevet, adattípust és attribútumot, amely meghatározza a mező használatát.
Ebben a példában az Azure.Search.Documents kódtár szinkron metódusait használjuk az egyszerűség és az olvashatóság érdekében. Éles forgatókönyvek esetén azonban aszinkron módszereket kell használnia az alkalmazás skálázható és rugalmas állapotának megőrzéséhez. Például a CreateIndexAsyncet használná a CreateIndex helyett.
A struktúrák meghatározása
Létrehozott két segédosztályt, Hotel.java és Address.java egy szállodai dokumentum struktúrájának és címének meghatározásához. A Hotel osztály tartalmazza a szállodaazonosító, a név, a leírás, a kategória, a címkék, a parkolás, a felújítás dátuma, az értékelés és a cím mezőit. A Cím osztály tartalmazza az utcacím, a város, az állam/tartomány, az irányítószám és az ország/régió mezőit.
Az Azure.Search.Documents ügyfélkódtárban a SearchableField és a SimpleField használatával egyszerűsítheti a meződefiníciókat.
-
SimpleField
bármilyen adattípus lehet, mindig nem kereshető (teljes szöveges keresési lekérdezések esetén figyelmen kívül hagyva), és lekérdezhető (nem rejtett). Más attribútumok alapértelmezés szerint ki vannak kapcsolva, de engedélyezhetők. Előfordulhat, hogy a SimpleFieldet csak szűrőkben, aspektusokban vagy pontozási profilokban használt dokumentumazonosítókhoz vagy mezőkhöz használja. Ha igen, mindenképpen alkalmazzon minden olyan attribútumot, amely a forgatókönyvhöz szükséges, például isKey = igaz a dokumentumazonosítóhoz. -
SearchableField
sztringnek kell lennie, és mindig kereshető és lekérdezhető. Más attribútumok alapértelmezés szerint ki vannak kapcsolva, de engedélyezhetők. Mivel ez a mezőtípus kereshető, támogatja a szinonimákat és az elemző tulajdonságainak teljes kiegészítését.
Akár az alapszintű SearchField
API-t, akár az egyik segédmodellt használja, explicit módon engedélyeznie kell a szűrési, aspektus- és rendezési attribútumokat. Például, isFilterable
, isSortable
és isFacetable
explicit módon kell hozzárendelni, ahogy az előző példában is látható.
Keresési index létrehozása
Ebben App.java
az esetben létrehoz egy SearchIndex
objektumot a main
metódusban, majd meghívja a createOrUpdateIndex
metódust az index létrehozásához a keresési szolgáltatásban. Az index tartalmaz egy SearchSuggester
automatikus kiegészítést is a megadott mezőkön.
// Create Search Index for Hotel model
searchIndexClient.createOrUpdateIndex(
new SearchIndex(indexName, SearchIndexClient.buildSearchFields(Hotel.class, null))
.setSuggesters(new SearchSuggester("sg", Arrays.asList("HotelName"))));
Dokumentumok betöltése
Az Azure AI Search a szolgáltatásban tárolt tartalmakon keres. Ebben a lépésben olyan JSON-dokumentumokat tölt be, amelyek megfelelnek a létrehozott szállodaindexnek.
Az Azure AI Searchben a keresési dokumentumok olyan adatstruktúrák, amelyek egyaránt bemenetek az indexeléshez és a lekérdezésekből származó kimenetekhez. A külső adatforrásból származó dokumentumbemenetek lehetnek egy adatbázis sorai, blobok a Blob Storage-ban vagy a lemezen lévő JSON-dokumentumok. Ebben a példában egy parancsikont hozunk létre, és négy szállodához ágyazunk be JSON-dokumentumokat magában a kódban.
Dokumentumok feltöltésekor IndexDocumentsBatch objektumot kell használnia. Az IndexDocumentsBatch
objektumok az IndexActions gyűjteményét tartalmazzák, amelyek mindegyike tartalmaz egy dokumentumot és egy tulajdonságot, amely közli az Azure AI Search szolgáltatással, hogy milyen műveletet kell végrehajtania (feltöltés, egyesítés, törlés és mergeOrUpload).
Ebben a fájlban App.java
dokumentumokat és indexműveleteket hozhat létre, majd továbbíthatja őket a következőnek IndexDocumentsBatch
: Az alábbi dokumentumok megfelelnek a szállodai osztály által meghatározott, a hotels-quickstart indexnek.
private static void uploadDocuments(SearchClient searchClient)
{
var hotelList = new ArrayList<Hotel>();
var hotel = new Hotel();
hotel.hotelId = "1";
hotel.hotelName = "Stay-Kay City Hotel";
hotel.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 Time's 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.";
hotel.descriptionFr = "L'hôtel est idéalement situé sur la principale artère commerciale de la ville en plein cœur de New York. A quelques minutes se trouve la place du temps et le centre historique de la ville, ainsi que d'autres lieux d'intérêt qui font de New York l'une des villes les plus attractives et cosmopolites de l'Amérique.";
hotel.category = "Boutique";
hotel.tags = new String[] { "pool", "air conditioning", "concierge" };
hotel.parkingIncluded = false;
hotel.lastRenovationDate = OffsetDateTime.of(LocalDateTime.of(LocalDate.of(1970, 1, 18), LocalTime.of(0, 0)), ZoneOffset.UTC);
hotel.rating = 3.6;
hotel.address = new Address();
hotel.address.streetAddress = "677 5th Ave";
hotel.address.city = "New York";
hotel.address.stateProvince = "NY";
hotel.address.postalCode = "10022";
hotel.address.country = "USA";
hotelList.add(hotel);
// REDACTED FOR BREVITY
var batch = new IndexDocumentsBatch<Hotel>();
batch.addMergeOrUploadActions(hotelList);
try
{
searchClient.indexDocuments(batch);
}
catch (Exception e)
{
e.printStackTrace();
// If for some reason any documents are dropped during indexing, you can compensate by delaying and
// retrying. This simple demo just logs failure and continues
System.err.println("Failed to index some of the documents");
}
}
Az objektum inicializálása IndexDocumentsBatch
után elküldheti azt az indexbe az objektum indexdokumentsSearchClient
meghívásával.
A Dokumentumok betöltése a SearchClient main()
használatával történik, de a művelethez rendszergazdai jogosultságok is szükségesek a szolgáltatáshoz, amely általában a SearchIndexClienthez van társítva. A művelet beállításának egyik módja a SearchClient beolvasása SearchIndexClient
(searchIndexClient
ebben a példában).
uploadDocuments(searchClient);
Mivel van egy konzolalkalmazásunk, amely az összes parancsot egymás után futtatja, 2 másodperces várakozási időt adunk hozzá az indexelés és a lekérdezések között.
// Wait 2 seconds for indexing to complete before starting queries (for demo and console-app purposes only)
System.out.println("Waiting for indexing...\n");
try
{
Thread.sleep(2000);
}
catch (InterruptedException e)
{
}
A 2 másodperces késleltetés kompenzálja az indexelést, amely aszinkron, így az összes dokumentum indexelhető a lekérdezések végrehajtása előtt. A késésben történő kódolás általában csak demókban, tesztekben és mintaalkalmazásokban szükséges.
Keresés az indexekben
Az első dokumentum indexelése után azonnal lekérheti a lekérdezési eredményeket, de az index tényleges tesztelésének várnia kell, amíg az összes dokumentum indexel.
Ez a szakasz két funkciót ad hozzá: lekérdezési logikát és eredményeket. Lekérdezésekhez használja a Keresés metódust. Ez a metódus a keresési szöveget (a lekérdezési sztringet) és más beállításokat használja.
Ebben App.java
a metódus a WriteDocuments
keresési eredményeket a konzolon nyomtatja ki.
// Write search results to console
private static void WriteSearchResults(SearchPagedIterable searchResults)
{
searchResults.iterator().forEachRemaining(result ->
{
Hotel hotel = result.getDocument(Hotel.class);
System.out.println(hotel);
});
System.out.println();
}
// Write autocomplete results to console
private static void WriteAutocompleteResults(AutocompletePagedIterable autocompleteResults)
{
autocompleteResults.iterator().forEachRemaining(result ->
{
String text = result.getText();
System.out.println(text);
});
System.out.println();
}
1. lekérdezési példa
A RunQueries
metódus lekérdezéseket hajt végre, és eredményeket ad vissza. Az eredmények hotelobjektumok. Ez a minta a metódus aláírását és az első lekérdezést mutatja be. Ez a lekérdezés bemutatja azt a Select
paramétert, amely lehetővé teszi az eredmény megírását a dokumentum kijelölt mezőivel.
// Run queries, use WriteDocuments to print output
private static void RunQueries(SearchClient searchClient)
{
// Query 1
System.out.println("Query #1: Search on empty term '*' to return all documents, showing a subset of fields...\n");
SearchOptions options = new SearchOptions();
options.setIncludeTotalCount(true);
options.setFilter("");
options.setOrderBy("");
options.setSelect("HotelId", "HotelName", "Address/City");
WriteSearchResults(searchClient.search("*", options, Context.NONE));
}
2. lekérdezési példa
A második lekérdezésben keressen rá egy kifejezésre, adjon hozzá egy szűrőt, amely kiválasztja a 4-nél nagyobb minősítést tartalmazó dokumentumokat, majd csökkenő sorrendben rendezi az értékelés szerint. A szűrő egy logikai kifejezés, amelyet egy index mezői értékelnek isFilterable
ki. A szűrő lekérdezések tartalmazhatnak vagy kizárnak értékeket. Ezért nincs relevanciapont társítva egy szűrő lekérdezéshez.
// Query 2
System.out.println("Query #2: Search on 'hotels', filter on 'Rating gt 4', sort by Rating in descending order...\n");
options = new SearchOptions();
options.setFilter("Rating gt 4");
options.setOrderBy("Rating desc");
options.setSelect("HotelId", "HotelName", "Rating");
WriteSearchResults(searchClient.search("hotels", options, Context.NONE));
3. lekérdezési példa
A harmadik lekérdezés egy teljes szöveges keresési művelet adott mezőkre való hatókörét mutatja be searchFields
.
// Query 3
System.out.println("Query #3: Limit search to specific fields (pool in Tags field)...\n");
options = new SearchOptions();
options.setSearchFields("Tags");
options.setSelect("HotelId", "HotelName", "Tags");
WriteSearchResults(searchClient.search("pool", options, Context.NONE));
4. lekérdezési példa
A negyedik lekérdezés bemutatja facets
, hogy milyen strukturált navigációs szerkezetek hozhatók létre.
// Query 4
System.out.println("Query #4: Facet on 'Category'...\n");
options = new SearchOptions();
options.setFilter("");
options.setFacets("Category");
options.setSelect("HotelId", "HotelName", "Category");
WriteSearchResults(searchClient.search("*", options, Context.NONE));
5. lekérdezési példa
Az ötödik lekérdezésben adjon vissza egy adott dokumentumot.
// Query 5
System.out.println("Query #5: Look up a specific document...\n");
Hotel lookupResponse = searchClient.getDocument("3", Hotel.class);
System.out.println(lookupResponse.hotelId);
System.out.println();
6. lekérdezési példa
Az utolsó lekérdezés az automatikus kiegészítés szintaxisát jeleníti meg, szimulálva az s részleges felhasználói bemenetét, amely két lehetséges egyezésre oldódik fel az sourceFields
indexben definiált javaslatotevőhöz társítva.
// Query 6
System.out.println("Query #6: Call Autocomplete on HotelName that starts with 's'...\n");
WriteAutocompleteResults(searchClient.autocomplete("s", "sg"));
Lekérdezések összegzése
Az előző lekérdezések több módon is egyeztetik a kifejezéseket a lekérdezésekben: teljes szöveges keresés, szűrők és automatikus kiegészítés.
A teljes szöveges keresés és a szűrők a SearchClient.search metódussal hajthatók végre. A keresési lekérdezések átadhatók a sztringben searchText
, míg egy szűrőkifejezés átadható a filter
SearchOptions osztály tulajdonságában. Keresés nélküli szűréshez egyszerűen adja meg a "*" értéket a searchText
search
metódus paraméteréhez. Ha szűrés nélkül szeretne keresni, hagyja meg a filter
tulajdonságot, vagy egyáltalán ne adja át a példányt SearchOptions
.
Megtudhatja, hogyan hozhat létre, tölthet be és kérdezhet le keresési indexet az Azure.Search.Documents ügyféloldali kódtár használatával a teljes szöveges keresés mintaadataival. A teljes szöveges keresés az Apache Lucene-t használja az indexeléshez és a lekérdezésekhez, valamint egy BM25 rangsorolási algoritmust a pontozási eredményekhez.
Ez a rövid útmutató létrehoz és lekérdez egy kisméretű, négy szállodára vonatkozó adatokat tartalmazó rövid útmutató-indexet.
Tipp.
Letöltheti a forráskódot, hogy befejezett projekttel kezdjen, vagy kövesse az alábbi lépéseket a saját létrehozásához.
Előfeltételek
- Aktív Azure-előfizetés – Ingyenes létrehozás
- Azure AI-Search szolgáltatás. Ha nincs ilyen szolgáltatása, hozzon létre egy szolgáltatást . Ehhez a rövid útmutatóhoz ingyenes szintet használhat.
A Microsoft Entra ID előfeltételei
A Microsoft Entra-azonosítóval javasolt kulcs nélküli hitelesítéshez a következőket kell elvégeznie:
- Telepítse a Kulcs nélküli hitelesítéshez használt Azure CLI-t a Microsoft Entra-azonosítóval.
- Rendelje hozzá mindkét
Search Service Contributor
Search Index Data Contributor
szerepkört a felhasználói fiókjához. Szerepköröket az Azure Portalon rendelhet hozzá a Hozzáférés-vezérlés (IAM)>Szerepkör-hozzárendelés hozzáadása területen. További információ: Csatlakozás az Azure AI Searchhez szerepkörök használatával.
Erőforrásadatok lekérése
Az alkalmazás Azure AI-Search szolgáltatás történő hitelesítéséhez le kell kérnie a következő adatokat:
Változó neve | Érték |
---|---|
SEARCH_API_ENDPOINT |
Ez az érték az Azure Portalon található. Válassza ki a keresési szolgáltatást, majd a bal oldali menüben válassza az Áttekintés lehetőséget. Az Essentials alatt található URL-érték a szükséges végpont. A végpontok például a következőképpen nézhetnek ki: https://mydemo.search.windows.net . |
További információ a kulcs nélküli hitelesítésről és a környezeti változók beállításáról.
Beállítás
Hozzon létre egy új mappát
full-text-quickstart
, amely tartalmazza az alkalmazást, és nyissa meg a Visual Studio Code-ot abban a mappában a következő paranccsal:mkdir full-text-quickstart && cd full-text-quickstart
Hozza létre a
package.json
következő paranccsal:npm init -y
Telepítse az Azure AI Search ügyfélkódtárát (Azure.Search.Documents) JavaScripthez a következőkkel:
npm install @azure/search-documents
Az ajánlott jelszó nélküli hitelesítéshez telepítse az Azure Identity ügyfélkódtárat a következőkkel:
npm install @azure/identity
Keresési index létrehozása, betöltése és lekérdezése
Az előző beállítási szakaszban telepítette az Azure AI Search ügyfélkódtárat és más függőségeket.
Ebben a szakaszban kódot ad hozzá egy keresési index létrehozásához, dokumentumokkal való betöltéséhez és lekérdezések futtatásához. Futtassa a programot az eredmények megtekintéséhez a konzolon. A kód részletes magyarázatát a kódszakaszban találja.
A rövid útmutatóban szereplő mintakód a Microsoft Entra-azonosítót használja az ajánlott kulcs nélküli hitelesítéshez. Ha inkább API-kulcsot szeretne használni, lecserélheti az DefaultAzureCredential
objektumot egy objektumra AzureKeyCredential
.
String searchServiceEndpoint = "https://<Put your search service NAME here>.search.windows.net/";
DefaultAzureCredential credential = new DefaultAzureCredentialBuilder().build();
Hozzon létre egy index.js nevű új fájlt, és illessze be a következő kódot a index.js:
// Import from the @azure/search-documents library import { SearchIndexClient, odata } from "@azure/search-documents"; // Import from the Azure Identity library import { DefaultAzureCredential } from "@azure/identity"; // Importing the hotels sample data import hotelData from './hotels.json' assert { type: "json" }; // Load the .env file if it exists import * as dotenv from "dotenv"; dotenv.config(); // Defining the index definition const indexDefinition = { "name": "hotels-quickstart", "fields": [ { "name": "HotelId", "type": "Edm.String", "key": true, "filterable": true }, { "name": "HotelName", "type": "Edm.String", "searchable": true, "filterable": false, "sortable": true, "facetable": false }, { "name": "Description", "type": "Edm.String", "searchable": true, "filterable": false, "sortable": false, "facetable": false, "analyzerName": "en.lucene" }, { "name": "Description_fr", "type": "Edm.String", "searchable": true, "filterable": false, "sortable": false, "facetable": false, "analyzerName": "fr.lucene" }, { "name": "Category", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true }, { "name": "Tags", "type": "Collection(Edm.String)", "searchable": true, "filterable": true, "sortable": false, "facetable": true }, { "name": "ParkingIncluded", "type": "Edm.Boolean", "filterable": true, "sortable": true, "facetable": true }, { "name": "LastRenovationDate", "type": "Edm.DateTimeOffset", "filterable": true, "sortable": true, "facetable": true }, { "name": "Rating", "type": "Edm.Double", "filterable": true, "sortable": true, "facetable": true }, { "name": "Address", "type": "Edm.ComplexType", "fields": [ { "name": "StreetAddress", "type": "Edm.String", "filterable": false, "sortable": false, "facetable": false, "searchable": true }, { "name": "City", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true }, { "name": "StateProvince", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true }, { "name": "PostalCode", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true }, { "name": "Country", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true } ] } ], "suggesters": [ { "name": "sg", "searchMode": "analyzingInfixMatching", "sourceFields": [ "HotelName" ] } ] }; async function main() { // Your search service endpoint const searchServiceEndpoint = "https://<Put your search service NAME here>.search.windows.net/"; // Use the recommended keyless credential instead of the AzureKeyCredential credential. const credential = new DefaultAzureCredential(); //const credential = new AzureKeyCredential(Your search service admin key); // Create a SearchIndexClient to send create/delete index commands const searchIndexClient = new SearchIndexClient(searchServiceEndpoint, credential); // Creating a search client to upload documents and issue queries const indexName = "hotels-quickstart"; const searchClient = searchIndexClient.getSearchClient(indexName); console.log('Checking if index exists...'); await deleteIndexIfExists(searchIndexClient, indexName); console.log('Creating index...'); let index = await searchIndexClient.createIndex(indexDefinition); console.log(`Index named ${index.name} has been created.`); console.log('Uploading documents...'); let indexDocumentsResult = await searchClient.mergeOrUploadDocuments(hotelData['value']); console.log(`Index operations succeeded: ${JSON.stringify(indexDocumentsResult.results[0].succeeded)} `); // waiting one second for indexing to complete (for demo purposes only) sleep(1000); console.log('Querying the index...'); console.log(); await sendQueries(searchClient); } async function deleteIndexIfExists(searchIndexClient, indexName) { try { await searchIndexClient.deleteIndex(indexName); console.log('Deleting index...'); } catch { console.log('Index does not exist yet.'); } } async function sendQueries(searchClient) { // Query 1 console.log('Query #1 - search everything:'); let searchOptions = { includeTotalCount: true, select: ["HotelId", "HotelName", "Rating"] }; let searchResults = await searchClient.search("*", searchOptions); for await (const result of searchResults.results) { console.log(`${JSON.stringify(result.document)}`); } console.log(`Result count: ${searchResults.count}`); console.log(); // Query 2 console.log('Query #2 - search with filter, orderBy, and select:'); let state = 'FL'; searchOptions = { filter: odata `Address/StateProvince eq ${state}`, orderBy: ["Rating desc"], select: ["HotelId", "HotelName", "Rating"] }; searchResults = await searchClient.search("wifi", searchOptions); for await (const result of searchResults.results) { console.log(`${JSON.stringify(result.document)}`); } console.log(); // Query 3 console.log('Query #3 - limit searchFields:'); searchOptions = { select: ["HotelId", "HotelName", "Rating"], searchFields: ["HotelName"] }; searchResults = await searchClient.search("sublime cliff", searchOptions); for await (const result of searchResults.results) { console.log(`${JSON.stringify(result.document)}`); } console.log(); // Query 4 console.log('Query #4 - limit searchFields and use facets:'); searchOptions = { facets: ["Category"], select: ["HotelId", "HotelName", "Rating"], searchFields: ["HotelName"] }; searchResults = await searchClient.search("*", searchOptions); for await (const result of searchResults.results) { console.log(`${JSON.stringify(result.document)}`); } console.log(); // Query 5 console.log('Query #5 - Lookup document:'); let documentResult = await searchClient.getDocument('3'); console.log(`HotelId: ${documentResult.HotelId}; HotelName: ${documentResult.HotelName}`); console.log(); } function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } main().catch((err) => { console.error("The sample encountered an error:", err); });
Hozzon létre egy hotels.json nevű fájlt, és illessze be a következő kódot hotels.json:
{ "value": [ { "HotelId": "1", "HotelName": "Secret Point Motel", "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 Time's 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.", "Description_fr": "L'hôtel est idéalement situé sur la principale artère commerciale de la ville en plein cœur de New York. A quelques minutes se trouve la place du temps et le centre historique de la ville, ainsi que d'autres lieux d'intérêt qui font de New York l'une des villes les plus attractives et cosmopolites de l'Amérique.", "Category": "Boutique", "Tags": ["pool", "air conditioning", "concierge"], "ParkingIncluded": false, "LastRenovationDate": "1970-01-18T00:00:00Z", "Rating": 3.6, "Address": { "StreetAddress": "677 5th Ave", "City": "New York", "StateProvince": "NY", "PostalCode": "10022" } }, { "HotelId": "2", "HotelName": "Twin Dome Motel", "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.", "Description_fr": "L'hôtel est situé dans une place du XIXe siècle, qui a été agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel moderne, fonctionnel et de première classe dans lequel l'art et les éléments historiques uniques coexistent avec le confort le plus moderne.", "Category": "Boutique", "Tags": ["pool", "free wifi", "concierge"], "ParkingIncluded": "false", "LastRenovationDate": "1979-02-18T00:00:00Z", "Rating": 3.6, "Address": { "StreetAddress": "140 University Town Center Dr", "City": "Sarasota", "StateProvince": "FL", "PostalCode": "34243" } }, { "HotelId": "3", "HotelName": "Triple Landscape Hotel", "Description": "The Hotel stands out for its gastronomic excellence under the management of William Dough, who advises on and oversees all of the Hotel’s restaurant services.", "Description_fr": "L'hôtel est situé dans une place du XIXe siècle, qui a été agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel moderne, fonctionnel et de première classe dans lequel l'art et les éléments historiques uniques coexistent avec le confort le plus moderne.", "Category": "Resort and Spa", "Tags": ["air conditioning", "bar", "continental breakfast"], "ParkingIncluded": "true", "LastRenovationDate": "2015-09-20T00:00:00Z", "Rating": 4.8, "Address": { "StreetAddress": "3393 Peachtree Rd", "City": "Atlanta", "StateProvince": "GA", "PostalCode": "30326" } }, { "HotelId": "4", "HotelName": "Sublime Cliff Hotel", "Description": "Sublime Cliff Hotel is located in the heart of the historic center of Sublime in an extremely vibrant and lively area within short walking distance to the sites and landmarks of the city and is surrounded by the extraordinary beauty of churches, buildings, shops and monuments. Sublime Cliff is part of a lovingly restored 1800 palace.", "Description_fr": "Le sublime Cliff Hotel est situé au coeur du centre historique de sublime dans un quartier extrêmement animé et vivant, à courte distance de marche des sites et monuments de la ville et est entouré par l'extraordinaire beauté des églises, des bâtiments, des commerces et Monuments. Sublime Cliff fait partie d'un Palace 1800 restauré avec amour.", "Category": "Boutique", "Tags": ["concierge", "view", "24-hour front desk service"], "ParkingIncluded": true, "LastRenovationDate": "1960-02-06T00:00:00Z", "Rating": 4.6, "Address": { "StreetAddress": "7400 San Pedro Ave", "City": "San Antonio", "StateProvince": "TX", "PostalCode": "78216" } } ] }
Hozzon létre egy hotels_quickstart_index.json nevű fájlt, és illessze be a következő kódot hotels_quickstart_index.json:
{ "name": "hotels-quickstart", "fields": [ { "name": "HotelId", "type": "Edm.String", "key": true, "filterable": true }, { "name": "HotelName", "type": "Edm.String", "searchable": true, "filterable": false, "sortable": true, "facetable": false }, { "name": "Description", "type": "Edm.String", "searchable": true, "filterable": false, "sortable": false, "facetable": false, "analyzerName": "en.lucene" }, { "name": "Description_fr", "type": "Edm.String", "searchable": true, "filterable": false, "sortable": false, "facetable": false, "analyzerName": "fr.lucene" }, { "name": "Category", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true }, { "name": "Tags", "type": "Collection(Edm.String)", "searchable": true, "filterable": true, "sortable": false, "facetable": true }, { "name": "ParkingIncluded", "type": "Edm.Boolean", "filterable": true, "sortable": true, "facetable": true }, { "name": "LastRenovationDate", "type": "Edm.DateTimeOffset", "filterable": true, "sortable": true, "facetable": true }, { "name": "Rating", "type": "Edm.Double", "filterable": true, "sortable": true, "facetable": true }, { "name": "Address", "type": "Edm.ComplexType", "fields": [ { "name": "StreetAddress", "type": "Edm.String", "filterable": false, "sortable": false, "facetable": false, "searchable": true }, { "name": "City", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true }, { "name": "StateProvince", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true }, { "name": "PostalCode", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true }, { "name": "Country", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "facetable": true } ] } ], "suggesters": [ { "name": "sg", "searchMode": "analyzingInfixMatching", "sourceFields": [ "HotelName" ] } ] }
Jelentkezzen be az Azure-ba a következő paranccsal:
az login
Futtassa a JavaScript-kódot a következő paranccsal:
node index.js
A kód ismertetése
Index létrehozása
A hotels_quickstart_index.json fájl határozza meg, hogyan működik az Azure AI Search a következő lépésben betöltődő dokumentumokkal. Az egyes mezőket egy name
adott mező azonosítja, és rendelkezik egy megadott type
mezővel. Minden mező indexattribútumok sorozatával is rendelkezik, amelyek meghatározzák, hogy az Azure AI Search képes-e keresni, szűrni, rendezni és kezelni a mezőt. A mezők többsége egyszerű adattípus, de néhány olyan összetett típus, amely AddressType
lehetővé teszi, hogy gazdag adatstruktúrákat hozzon létre az indexben. A támogatott adattípusokról és indexattribútumokról az Index létrehozása (REST) című témakörben olvashat bővebben.
Az indexdefinícióval a index.js tetején szeretnénk importálni hotels_quickstart_index.json, hogy a fő függvény hozzáférhessen az indexdefinícióhoz.
const indexDefinition = require('./hotels_quickstart_index.json');
A fő függvényen belül létrehozunk egy SearchIndexClient
, az Azure AI Search indexeinek létrehozására és kezelésére szolgáló parancsot.
const indexClient = new SearchIndexClient(endpoint, new AzureKeyCredential(apiKey));
Ezután törölni szeretnénk az indexet, ha már létezik. Ez a művelet a tesztelési/demókódok gyakori gyakorlata.
Ehhez definiálunk egy egyszerű függvényt, amely megpróbálja törölni az indexet.
async function deleteIndexIfExists(indexClient, indexName) {
try {
await indexClient.deleteIndex(indexName);
console.log('Deleting index...');
} catch {
console.log('Index does not exist yet.');
}
}
A függvény futtatásához kinyerjük az index nevét az indexdefinícióból, és átadjuk a indexName
függvénynekdeleteIndexIfExists()
.indexClient
const indexName = indexDefinition["name"];
console.log('Checking if index exists...');
await deleteIndexIfExists(indexClient, indexName);
Ezután készen állunk az index metódussal való létrehozására createIndex()
.
console.log('Creating index...');
let index = await indexClient.createIndex(indexDefinition);
console.log(`Index named ${index.name} has been created.`);
Dokumentumok betöltése
Az Azure AI Searchben a dokumentumok olyan adatstruktúrák, amelyek egyaránt bemenetek az indexeléshez és a lekérdezésekből származó kimenetekhez. Ezeket az adatokat leküldheti az indexbe, vagy használhat indexelőt. Ebben az esetben programozott módon leküldjük a dokumentumokat az indexbe.
A dokumentumbemenetek lehetnek egy adatbázis sorai, blobok a Blob Storage-ban, vagy a mintában szereplő JSON-dokumentumok a lemezen. A művelethez hasonlóan a indexDefinition
index.js tetején is importálnunk hotels.json
kell, hogy az adatok elérhetők legyenek a fő függvényünkben.
const hotelData = require('./hotels.json');
Ha adatokat szeretne indexelni a keresési indexbe, létre kell hoznunk egy SearchClient
. Bár az SearchIndexClient
indexek létrehozására és kezelésére szolgál, a SearchClient
dokumentumok feltöltésére és az index lekérdezésére szolgál.
Kétféleképpen hozhat létre .SearchClient
Az első lehetőség a nulláról történő létrehozás SearchClient
:
const searchClient = new SearchClient(endpoint, indexName, new AzureKeyCredential(apiKey));
Másik lehetőségként a getSearchClient()
következő metódus SearchIndexClient
használatával is létrehozhatja a következőt SearchClient
:
const searchClient = indexClient.getSearchClient(indexName);
Az ügyfél definiálása után töltse fel a dokumentumokat a keresési indexbe. Ebben az esetben a metódust mergeOrUploadDocuments()
használjuk, amely feltölti a dokumentumokat, vagy egyesíti őket egy meglévő dokumentummal, ha már létezik ugyanazzal a kulccsal rendelkező dokumentum.
console.log('Uploading documents...');
let indexDocumentsResult = await searchClient.mergeOrUploadDocuments(hotelData['value']);
console.log(`Index operations succeeded: ${JSON.stringify(indexDocumentsResult.results[0].succeeded)}`);
Keresés az indexekben
Egy index létrehozásával és a feltöltött dokumentumokkal lekérdezéseket küldhet az indexnek. Ebben a szakaszban öt különböző lekérdezést küldünk a keresési indexbe, hogy bemutassuk az Ön számára elérhető különböző lekérdezési funkciókat.
A lekérdezések egy sendQueries()
függvényben vannak megírva, amelyet a fő függvényben hívunk meg az alábbiak szerint:
await sendQueries(searchClient);
A rendszer a lekérdezéseket a search()
következő módszerrel küldi searchClient
el: . Az első paraméter a keresési szöveg, a második pedig a keresési beállításokat adja meg.
1. lekérdezési példa
Az első lekérdezés minden *
kereséssel egyenértékű, és az index három mezőjét választja ki. Ajánlott csak a szükséges mezőket használni select
, mert a szükségtelen adatok visszakérése késést okozhat a lekérdezésekben.
A searchOptions
lekérdezés értéke is a következőre true
van includeTotalCount
állítva, amely a talált találatok számát adja vissza.
async function sendQueries(searchClient) {
console.log('Query #1 - search everything:');
let searchOptions = {
includeTotalCount: true,
select: ["HotelId", "HotelName", "Rating"]
};
let searchResults = await searchClient.search("*", searchOptions);
for await (const result of searchResults.results) {
console.log(`${JSON.stringify(result.document)}`);
}
console.log(`Result count: ${searchResults.count}`);
// remaining queries go here
}
Az alább ismertetett többi lekérdezést is hozzá kell adni a sendQueries()
függvényhez. Itt külön vannak elválasztva az olvashatóság érdekében.
2. lekérdezési példa
A következő lekérdezésben megadjuk a keresési kifejezést "wifi"
, és egy szűrőt is belefoglalunk, amely csak olyan eredményeket ad vissza, ahol az állapot egyenlő 'FL'
. Az eredményeket a szálloda is rendezi Rating
.
console.log('Query #2 - Search with filter, orderBy, and select:');
let state = 'FL';
searchOptions = {
filter: odata`Address/StateProvince eq ${state}`,
orderBy: ["Rating desc"],
select: ["HotelId", "HotelName", "Rating"]
};
searchResults = await searchClient.search("wifi", searchOptions);
for await (const result of searchResults.results) {
console.log(`${JSON.stringify(result.document)}`);
}
3. lekérdezési példa
Ezután a keresés egyetlen kereshető mezőre korlátozódik a searchFields
paraméter használatával. Ez a megközelítés nagyszerű lehetőség arra, hogy hatékonyabbá tegye a lekérdezést, ha tudja, hogy csak bizonyos mezőkben lévő egyezések érdeklik.
console.log('Query #3 - Limit searchFields:');
searchOptions = {
select: ["HotelId", "HotelName", "Rating"],
searchFields: ["HotelName"]
};
searchResults = await searchClient.search("Sublime Palace", searchOptions);
for await (const result of searchResults.results) {
console.log(`${JSON.stringify(result.document)}`);
}
console.log();
4. lekérdezési példa
Egy másik gyakori lehetőség a lekérdezésbe való belefoglalás.facets
Az aspektusok segítségével szűrőket hozhat létre a felhasználói felületen, így a felhasználók könnyen megismerhetik, hogy milyen értékekre szűrhetnek le.
console.log('Query #4 - Use facets:');
searchOptions = {
facets: ["Category"],
select: ["HotelId", "HotelName", "Rating"],
searchFields: ["HotelName"]
};
searchResults = await searchClient.search("*", searchOptions);
for await (const result of searchResults.results) {
console.log(`${JSON.stringify(result.document)}`);
}
5. lekérdezési példa
A végső lekérdezés a getDocument()
searchClient
. Így hatékonyan lekérhet egy dokumentumot a kulcsával.
console.log('Query #5 - Lookup document:');
let documentResult = await searchClient.getDocument(key='3')
console.log(`HotelId: ${documentResult.HotelId}; HotelName: ${documentResult.HotelName}`)
Lekérdezések összegzése
Az előző lekérdezések több módon is egyeztetik a kifejezéseket a lekérdezésekben: teljes szöveges keresés, szűrők és automatikus kiegészítés.
A metódussal searchClient.search
teljes szöveges keresést és szűrőket hajtunk végre. A keresési lekérdezések átadhatók a sztringben searchText
, míg egy szűrőkifejezés átadható az filter
SearchOptions
osztály tulajdonságában. Keresés nélküli szűréshez egyszerűen adja meg a "*" értéket a searchText
search
metódus paraméteréhez. Ha szűrés nélkül szeretne keresni, hagyja meg a filter
tulajdonságot, vagy egyáltalán ne adja át a példányt SearchOptions
.
Megtudhatja, hogyan hozhat létre, tölthet be és kérdezhet le keresési indexet az Azure.Search.Documents ügyféloldali kódtár használatával a teljes szöveges keresés mintaadataival. A teljes szöveges keresés az Apache Lucene-t használja az indexeléshez és a lekérdezésekhez, valamint egy BM25 rangsorolási algoritmust a pontozási eredményekhez.
Ez a rövid útmutató létrehoz és lekérdez egy kisméretű, négy szállodára vonatkozó adatokat tartalmazó rövid útmutató-indexet.
Előfeltételek
- Aktív Azure-előfizetés – Ingyenes létrehozás
- Azure AI-Search szolgáltatás. Ha nincs ilyen szolgáltatása, hozzon létre egy szolgáltatást . Ehhez a rövid útmutatóhoz ingyenes szintet használhat.
- Visual Studio Code Python-bővítménnyel vagy azzal egyenértékű IDE-vel a Python 3.10 vagy újabb verziójával. Ha nem rendelkezik a Python megfelelő verziójával, kövesse a VS Code Python-oktatóanyag utasításait.
A Microsoft Entra ID előfeltételei
A Microsoft Entra-azonosítóval javasolt kulcs nélküli hitelesítéshez a következőket kell elvégeznie:
- Telepítse a Kulcs nélküli hitelesítéshez használt Azure CLI-t a Microsoft Entra-azonosítóval.
- Rendelje hozzá mindkét
Search Service Contributor
Search Index Data Contributor
szerepkört a felhasználói fiókjához. Szerepköröket az Azure Portalon rendelhet hozzá a Hozzáférés-vezérlés (IAM)>Szerepkör-hozzárendelés hozzáadása területen. További információ: Csatlakozás az Azure AI Searchhez szerepkörök használatával.
Erőforrásadatok lekérése
Az alkalmazás Azure AI-Search szolgáltatás történő hitelesítéséhez le kell kérnie a következő adatokat:
Változó neve | Érték |
---|---|
SEARCH_API_ENDPOINT |
Ez az érték az Azure Portalon található. Válassza ki a keresési szolgáltatást, majd a bal oldali menüben válassza az Áttekintés lehetőséget. Az Essentials alatt található URL-érték a szükséges végpont. A végpontok például a következőképpen nézhetnek ki: https://mydemo.search.windows.net . |
További információ a kulcs nélküli hitelesítésről és a környezeti változók beállításáról.
Saját környezet beállítása
A mintakódot egy Jupyter-jegyzetfüzetben futtatja. Ezért be kell állítania a környezetet a Jupyter-notebookok futtatásához.
Töltse le vagy másolja a mintajegyzetfüzetet a GitHubról.
Nyissa meg a jegyzetfüzetet a Visual Studio Code-ban.
Hozzon létre egy új Python-környezetet az oktatóanyaghoz szükséges csomagok telepítéséhez.
Fontos
Ne telepítsen csomagokat a globális Python-telepítésbe. Python-csomagok telepítésekor mindig használjon virtuális vagy conda környezetet, különben megszakíthatja a Python globális telepítését.
A beállítás eltarthat egy percig. Ha problémákba ütközik, tekintse meg a Python-környezeteket a VS Code-ban.
Telepítse a Jupyter-jegyzetfüzeteket és a Jupyter-jegyzetfüzetekhez készült IPython Kernelt, ha még nem rendelkezik velük.
pip install jupyter pip install ipykernel python -m ipykernel install --user --name=.venv
Válassza ki a jegyzetfüzet kernelét.
- A jegyzetfüzet jobb felső sarkában válassza a Kernel kiválasztása lehetőséget.
- Ha megjelenik
.venv
a listában, jelölje ki. Ha nem látja, válassza a Másik Kernel>Python-környezet kiválasztása>.venv
lehetőséget.
Keresési index létrehozása, betöltése és lekérdezése
Ebben a szakaszban kódot ad hozzá egy keresési index létrehozásához, dokumentumokkal való betöltéséhez és lekérdezések futtatásához. Futtassa a programot az eredmények megtekintéséhez a konzolon. A kód részletes magyarázatát a kódszakaszban találja.
Győződjön meg arról, hogy a jegyzetfüzet nyitva van a
.venv
kernelben az előző szakaszban leírtak szerint.Futtassa az első kódcellát a szükséges csomagok, köztük az azure-search-documents telepítéséhez.
! pip install azure-search-documents==11.6.0b1 --quiet ! pip install azure-identity --quiet ! pip install python-dotenv --quiet
Cserélje le a második kódcella tartalmát a következő kódra a hitelesítési módszertől függően.
Feljegyzés
A rövid útmutatóban szereplő mintakód a Microsoft Entra-azonosítót használja az ajánlott kulcs nélküli hitelesítéshez. Ha inkább API-kulcsot szeretne használni, lecserélheti az
DefaultAzureCredential
objektumot egy objektumraAzureKeyCredential
.from azure.core.credentials import AzureKeyCredential from azure.identity import DefaultAzureCredential, AzureAuthorityHosts search_endpoint: str = "https://<Put your search service NAME here>.search.windows.net/" authority = AzureAuthorityHosts.AZURE_PUBLIC_CLOUD credential = DefaultAzureCredential(authority=authority) index_name: str = "hotels-quickstart-python"
Távolítsa el az alábbi két sort az indexkód létrehozása cellából. A hitelesítő adatok már be vannak állítva az előző kódcellában.
from azure.core.credentials import AzureKeyCredential credential = AzureKeyCredential(search_api_key)
Keresési index létrehozásához futtassa az Indexkód létrehozása cellát.
Futtassa a többi kódcellát egymás után a dokumentumok betöltéséhez és a lekérdezések futtatásához.
A kód ismertetése
Index létrehozása
SearchIndexClient
az Azure AI Search indexeinek létrehozására és kezelésére szolgál. Az egyes mezőket egy name
adott mező azonosítja, és rendelkezik egy adott type
mezővel.
Minden mező indexattribútumok sorozatával is rendelkezik, amelyek meghatározzák, hogy az Azure AI Search képes-e keresni, szűrni, rendezni és kezelni a mezőt. A mezők többsége egyszerű adattípus, de néhány olyan összetett típus, amely AddressType
lehetővé teszi, hogy gazdag adatstruktúrákat hozzon létre az indexben. A támogatott adattípusokról és indexattribútumokról az Index létrehozása (REST) című témakörben olvashat bővebben.
Hasznos adatok létrehozása és dokumentumok feltöltése
A művelettípushoz használjon indexműveletet, például feltöltést vagy egyesítést és feltöltést. A dokumentumok a GitHub HotelsData-mintájából származnak.
Keresés az indexekben
Az első dokumentum indexelése után azonnal lekérheti a lekérdezési eredményeket, de az index tényleges tesztelésének várnia kell, amíg az összes dokumentum indexel.
Használja a search.client osztály keresési módszerét.
A jegyzetfüzetben található minta lekérdezések a következők:
- Alapszintű lekérdezés: Üres keresést hajt végre (
search=*
a keresési pontszám = 1,0) tetszőleges dokumentumokból álló üres listát ad vissza. Mivel nincsenek feltételek, minden dokumentum szerepel az eredmények között. - Kifejezéses lekérdezés: Egész kifejezéseket ad hozzá a keresési kifejezéshez ("wifi"). Ez a lekérdezés azt határozza meg, hogy az eredmények csak azokat a mezőket tartalmazzák az
select
utasításban. A visszaküldött mezők korlátozása minimálisra csökkenti a vezetéken visszaküldött adatok mennyiségét, és csökkenti a keresési késést. - Szűrt lekérdezés: Adjon hozzá egy szűrőkifejezést, amely csak a négynél nagyobb minősítésű szállodákat adja vissza csökkenő sorrendbe rendezve.
- Mezős hatókörkezelés: Hozzáadás
search_fields
a hatókör-lekérdezés végrehajtásához adott mezőkhöz. - Aspektusok: A keresési eredményekben található pozitív egyezések aspektusainak létrehozása. Nincsenek nulla egyezések. Ha a keresési eredmények nem tartalmazzák a wifi kifejezést, akkor a wifi nem jelenik meg az arculati navigációs struktúrában.
- Dokumentum keresése: Egy dokumentum visszaadása a kulcs alapján. Ez a művelet akkor hasznos, ha részletezni szeretné, ha egy felhasználó kiválaszt egy elemet egy keresési eredményben.
- Automatikus kiegészítés: Adja meg a lehetséges találatokat, amikor a felhasználó be van típusok a keresőmezőbe. Az automatikus kiegészítés egy javaslatot (
sg
) használ annak megismerésére, hogy mely mezők tartalmaznak lehetséges egyezéseket a javaslattevő kérésekhez. Ebben a rövid útmutatóban ezek a mezők a következőkTags
: ,Address/City
Address/Country
. Az automatikus kiegészítés szimulálásához adja meg az sa betűket részleges sztringként. A SearchClient automatikus kiegészítési metódusa visszaküldi a lehetséges kifejezés-egyezéseket.
Az index eltávolítása
Ha befejezte ezt az indexet, törölheti azt a Clean up kódcella futtatásával. A szükségtelen indexek törlése helyet szabadít fel a gyorsútmutatók és oktatóanyagok végiglépéséhez.
Megtudhatja, hogyan hozhat létre, tölthet be és kérdezhet le keresési indexet az Azure.Search.Documents ügyféloldali kódtár használatával a teljes szöveges keresés mintaadataival. A teljes szöveges keresés az Apache Lucene-t használja az indexeléshez és a lekérdezésekhez, valamint egy BM25 rangsorolási algoritmust a pontozási eredményekhez.
Ez a rövid útmutató létrehoz és lekérdez egy kisméretű, négy szállodára vonatkozó adatokat tartalmazó rövid útmutató-indexet.
Tipp.
Letöltheti a forráskódot, hogy befejezett projekttel kezdjen, vagy kövesse az alábbi lépéseket a saját létrehozásához.
Előfeltételek
- Aktív Azure-előfizetés – Ingyenes létrehozás
- Azure AI-Search szolgáltatás. Ha nincs ilyen szolgáltatása, hozzon létre egy szolgáltatást . Ehhez a rövid útmutatóhoz ingyenes szintet használhat.
A Microsoft Entra ID előfeltételei
A Microsoft Entra-azonosítóval javasolt kulcs nélküli hitelesítéshez a következőket kell elvégeznie:
- Telepítse a Kulcs nélküli hitelesítéshez használt Azure CLI-t a Microsoft Entra-azonosítóval.
- Rendelje hozzá mindkét
Search Service Contributor
Search Index Data Contributor
szerepkört a felhasználói fiókjához. Szerepköröket az Azure Portalon rendelhet hozzá a Hozzáférés-vezérlés (IAM)>Szerepkör-hozzárendelés hozzáadása területen. További információ: Csatlakozás az Azure AI Searchhez szerepkörök használatával.
Erőforrásadatok lekérése
Az alkalmazás Azure AI-Search szolgáltatás történő hitelesítéséhez le kell kérnie a következő adatokat:
Változó neve | Érték |
---|---|
SEARCH_API_ENDPOINT |
Ez az érték az Azure Portalon található. Válassza ki a keresési szolgáltatást, majd a bal oldali menüben válassza az Áttekintés lehetőséget. Az Essentials alatt található URL-érték a szükséges végpont. A végpontok például a következőképpen nézhetnek ki: https://mydemo.search.windows.net . |
További információ a kulcs nélküli hitelesítésről és a környezeti változók beállításáról.
Beállítás
Hozzon létre egy új mappát
full-text-quickstart
, amely tartalmazza az alkalmazást, és nyissa meg a Visual Studio Code-ot abban a mappában a következő paranccsal:mkdir full-text-quickstart && cd full-text-quickstart
Hozza létre a
package.json
következő paranccsal:npm init -y
Frissítse az
package.json
ECMAScriptet a következő paranccsal:npm pkg set type=module
Telepítse az Azure AI Search ügyfélkódtárát (Azure.Search.Documents) JavaScripthez a következőkkel:
npm install @azure/search-documents
Az ajánlott jelszó nélküli hitelesítéshez telepítse az Azure Identity ügyfélkódtárat a következőkkel:
npm install @azure/identity
Keresési index létrehozása, betöltése és lekérdezése
Az előző beállítási szakaszban telepítette az Azure AI Search ügyfélkódtárat és más függőségeket.
Ebben a szakaszban kódot ad hozzá egy keresési index létrehozásához, dokumentumokkal való betöltéséhez és lekérdezések futtatásához. Futtassa a programot az eredmények megtekintéséhez a konzolon. A kód részletes magyarázatát a kódszakaszban találja.
A rövid útmutatóban szereplő mintakód a Microsoft Entra-azonosítót használja az ajánlott kulcs nélküli hitelesítéshez. Ha inkább API-kulcsot szeretne használni, lecserélheti az DefaultAzureCredential
objektumot egy objektumra AzureKeyCredential
.
const searchServiceEndpoint = "https://<Put your search service NAME here>.search.windows.net/";
const credential = new DefaultAzureCredential();
Hozzon létre egy index.ts nevű új fájlt, és illessze be a következő kódot a index.ts:
// Import from the @azure/search-documents library import { SearchIndexClient, SearchClient, SearchFieldDataType, AzureKeyCredential, odata, SearchIndex } from "@azure/search-documents"; // Import from the Azure Identity library import { DefaultAzureCredential } from "@azure/identity"; // Importing the hotels sample data import hotelData from './hotels.json' assert { type: "json" }; // Load the .env file if it exists import * as dotenv from "dotenv"; dotenv.config(); // Defining the index definition const indexDefinition: SearchIndex = { "name": "hotels-quickstart", "fields": [ { "name": "HotelId", "type": "Edm.String" as SearchFieldDataType, "key": true, "filterable": true }, { "name": "HotelName", "type": "Edm.String" as SearchFieldDataType, "searchable": true, "filterable": false, "sortable": true, "facetable": false }, { "name": "Description", "type": "Edm.String" as SearchFieldDataType, "searchable": true, "filterable": false, "sortable": false, "facetable": false, "analyzerName": "en.lucene" }, { "name": "Description_fr", "type": "Edm.String" as SearchFieldDataType, "searchable": true, "filterable": false, "sortable": false, "facetable": false, "analyzerName": "fr.lucene" }, { "name": "Category", "type": "Edm.String" as SearchFieldDataType, "searchable": true, "filterable": true, "sortable": true, "facetable": true }, { "name": "Tags", "type": "Collection(Edm.String)", "searchable": true, "filterable": true, "sortable": false, "facetable": true }, { "name": "ParkingIncluded", "type": "Edm.Boolean", "filterable": true, "sortable": true, "facetable": true }, { "name": "LastRenovationDate", "type": "Edm.DateTimeOffset", "filterable": true, "sortable": true, "facetable": true }, { "name": "Rating", "type": "Edm.Double", "filterable": true, "sortable": true, "facetable": true }, { "name": "Address", "type": "Edm.ComplexType", "fields": [ { "name": "StreetAddress", "type": "Edm.String" as SearchFieldDataType, "filterable": false, "sortable": false, "facetable": false, "searchable": true }, { "name": "City", "type": "Edm.String" as SearchFieldDataType, "searchable": true, "filterable": true, "sortable": true, "facetable": true }, { "name": "StateProvince", "type": "Edm.String" as SearchFieldDataType, "searchable": true, "filterable": true, "sortable": true, "facetable": true }, { "name": "PostalCode", "type": "Edm.String" as SearchFieldDataType, "searchable": true, "filterable": true, "sortable": true, "facetable": true }, { "name": "Country", "type": "Edm.String" as SearchFieldDataType, "searchable": true, "filterable": true, "sortable": true, "facetable": true } ] } ], "suggesters": [ { "name": "sg", "searchMode": "analyzingInfixMatching", "sourceFields": [ "HotelName" ] } ] }; async function main() { // Your search service endpoint const searchServiceEndpoint = "https://<Put your search service NAME here>.search.windows.net/"; // Use the recommended keyless credential instead of the AzureKeyCredential credential. const credential = new DefaultAzureCredential(); //const credential = new AzureKeyCredential(Your search service admin key); // Create a SearchIndexClient to send create/delete index commands const searchIndexClient: SearchIndexClient = new SearchIndexClient( searchServiceEndpoint, credential ); // Creating a search client to upload documents and issue queries const indexName: string = "hotels-quickstart"; const searchClient: SearchClient<any> = searchIndexClient.getSearchClient(indexName); console.log('Checking if index exists...'); await deleteIndexIfExists(searchIndexClient, indexName); console.log('Creating index...'); let index: SearchIndex = await searchIndexClient.createIndex(indexDefinition); console.log(`Index named ${index.name} has been created.`); console.log('Uploading documents...'); let indexDocumentsResult = await searchClient.mergeOrUploadDocuments(hotelData['value']); console.log(`Index operations succeeded: ${JSON.stringify(indexDocumentsResult.results[0].succeeded)} `); // waiting one second for indexing to complete (for demo purposes only) sleep(1000); console.log('Querying the index...'); console.log(); await sendQueries(searchClient); } async function deleteIndexIfExists(searchIndexClient: SearchIndexClient, indexName: string) { try { await searchIndexClient.deleteIndex(indexName); console.log('Deleting index...'); } catch { console.log('Index does not exist yet.'); } } async function sendQueries(searchClient: SearchClient<any>) { // Query 1 console.log('Query #1 - search everything:'); let searchOptions: any = { includeTotalCount: true, select: ["HotelId", "HotelName", "Rating"] }; let searchResults = await searchClient.search("*", searchOptions); for await (const result of searchResults.results) { console.log(`${JSON.stringify(result.document)}`); } console.log(`Result count: ${searchResults.count}`); console.log(); // Query 2 console.log('Query #2 - search with filter, orderBy, and select:'); let state = 'FL'; searchOptions = { filter: odata`Address/StateProvince eq ${state}`, orderBy: ["Rating desc"], select: ["HotelId", "HotelName", "Rating"] }; searchResults = await searchClient.search("wifi", searchOptions); for await (const result of searchResults.results) { console.log(`${JSON.stringify(result.document)}`); } console.log(); // Query 3 console.log('Query #3 - limit searchFields:'); searchOptions = { select: ["HotelId", "HotelName", "Rating"], searchFields: ["HotelName"] }; searchResults = await searchClient.search("sublime cliff", searchOptions); for await (const result of searchResults.results) { console.log(`${JSON.stringify(result.document)}`); } console.log(); // Query 4 console.log('Query #4 - limit searchFields and use facets:'); searchOptions = { facets: ["Category"], select: ["HotelId", "HotelName", "Rating"], searchFields: ["HotelName"] }; searchResults = await searchClient.search("*", searchOptions); for await (const result of searchResults.results) { console.log(`${JSON.stringify(result.document)}`); } console.log(); // Query 5 console.log('Query #5 - Lookup document:'); let documentResult = await searchClient.getDocument('3'); console.log(`HotelId: ${documentResult.HotelId}; HotelName: ${documentResult.HotelName}`); console.log(); } function sleep(ms: number) { return new Promise(resolve => setTimeout(resolve, ms)); } main().catch((err) => { console.error("The sample encountered an error:", err); });
Hozzon létre egy hotels.json nevű fájlt, és illessze be a következő kódot hotels.json:
{ "value": [ { "HotelId": "1", "HotelName": "Secret Point Motel", "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 Time's 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.", "Description_fr": "L'hôtel est idéalement situé sur la principale artère commerciale de la ville en plein cœur de New York. A quelques minutes se trouve la place du temps et le centre historique de la ville, ainsi que d'autres lieux d'intérêt qui font de New York l'une des villes les plus attractives et cosmopolites de l'Amérique.", "Category": "Boutique", "Tags": ["pool", "air conditioning", "concierge"], "ParkingIncluded": false, "LastRenovationDate": "1970-01-18T00:00:00Z", "Rating": 3.6, "Address": { "StreetAddress": "677 5th Ave", "City": "New York", "StateProvince": "NY", "PostalCode": "10022" } }, { "HotelId": "2", "HotelName": "Twin Dome Motel", "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.", "Description_fr": "L'hôtel est situé dans une place du XIXe siècle, qui a été agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel moderne, fonctionnel et de première classe dans lequel l'art et les éléments historiques uniques coexistent avec le confort le plus moderne.", "Category": "Boutique", "Tags": ["pool", "free wifi", "concierge"], "ParkingIncluded": "false", "LastRenovationDate": "1979-02-18T00:00:00Z", "Rating": 3.6, "Address": { "StreetAddress": "140 University Town Center Dr", "City": "Sarasota", "StateProvince": "FL", "PostalCode": "34243" } }, { "HotelId": "3", "HotelName": "Triple Landscape Hotel", "Description": "The Hotel stands out for its gastronomic excellence under the management of William Dough, who advises on and oversees all of the Hotel’s restaurant services.", "Description_fr": "L'hôtel est situé dans une place du XIXe siècle, qui a été agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel moderne, fonctionnel et de première classe dans lequel l'art et les éléments historiques uniques coexistent avec le confort le plus moderne.", "Category": "Resort and Spa", "Tags": ["air conditioning", "bar", "continental breakfast"], "ParkingIncluded": "true", "LastRenovationDate": "2015-09-20T00:00:00Z", "Rating": 4.8, "Address": { "StreetAddress": "3393 Peachtree Rd", "City": "Atlanta", "StateProvince": "GA", "PostalCode": "30326" } }, { "HotelId": "4", "HotelName": "Sublime Cliff Hotel", "Description": "Sublime Cliff Hotel is located in the heart of the historic center of Sublime in an extremely vibrant and lively area within short walking distance to the sites and landmarks of the city and is surrounded by the extraordinary beauty of churches, buildings, shops and monuments. Sublime Cliff is part of a lovingly restored 1800 palace.", "Description_fr": "Le sublime Cliff Hotel est situé au coeur du centre historique de sublime dans un quartier extrêmement animé et vivant, à courte distance de marche des sites et monuments de la ville et est entouré par l'extraordinaire beauté des églises, des bâtiments, des commerces et Monuments. Sublime Cliff fait partie d'un Palace 1800 restauré avec amour.", "Category": "Boutique", "Tags": ["concierge", "view", "24-hour front desk service"], "ParkingIncluded": true, "LastRenovationDate": "1960-02-06T00:00:00Z", "Rating": 4.6, "Address": { "StreetAddress": "7400 San Pedro Ave", "City": "San Antonio", "StateProvince": "TX", "PostalCode": "78216" } } ] }
Hozza létre a fájlt a
tsconfig.json
TypeScript-kód fordításához, és másolja a következő kódot az ECMAScripthez.{ "compilerOptions": { "module": "NodeNext", "target": "ES2022", // Supports top-level await "moduleResolution": "NodeNext", "skipLibCheck": true, // Avoid type errors from node_modules "strict": true // Enable strict type-checking options }, "include": ["*.ts"] }
Transpile TypeScriptről JavaScriptre.
tsc
Jelentkezzen be az Azure-ba a következő paranccsal:
az login
Futtassa a JavaScript-kódot a következő paranccsal:
node index.js
A kód ismertetése
Index létrehozása
Hozzon létre egy fájl hotels_quickstart_index.json. Ez a fájl határozza meg, hogyan működik az Azure AI Search a következő lépésben betöltődő dokumentumokkal. Az egyes mezőket egy name
adott mező azonosítja, és rendelkezik egy megadott type
mezővel. Minden mező indexattribútumok sorozatával is rendelkezik, amelyek meghatározzák, hogy az Azure AI Search képes-e keresni, szűrni, rendezni és kezelni a mezőt. A mezők többsége egyszerű adattípus, de néhány olyan összetett típus, amely AddressType
lehetővé teszi, hogy gazdag adatstruktúrákat hozzon létre az indexben. A támogatott adattípusokról és indexattribútumokról az Index létrehozása (REST) című témakörben olvashat bővebben.
Importálni szeretnénk hotels_quickstart_index.json, hogy a fő függvény hozzáférhessen az indexdefinícióhoz.
import indexDefinition from './hotels_quickstart_index.json';
interface HotelIndexDefinition {
name: string;
fields: SimpleField[] | ComplexField[];
suggesters: SearchSuggester[];
};
const hotelIndexDefinition: HotelIndexDefinition = indexDefinition as HotelIndexDefinition;
A fő függvényen belül létrehozunk egy SearchIndexClient
, az Azure AI Search indexeinek létrehozására és kezelésére szolgáló parancsot.
const indexClient = new SearchIndexClient(endpoint, new AzureKeyCredential(apiKey));
Ezután törölni szeretnénk az indexet, ha már létezik. Ez a művelet a tesztelési/demókódok gyakori gyakorlata.
Ehhez definiálunk egy egyszerű függvényt, amely megpróbálja törölni az indexet.
async function deleteIndexIfExists(indexClient: SearchIndexClient, indexName: string): Promise<void> {
try {
await indexClient.deleteIndex(indexName);
console.log('Deleting index...');
} catch {
console.log('Index does not exist yet.');
}
}
A függvény futtatásához kinyerjük az index nevét az indexdefinícióból, és átadjuk a indexName
függvénynekdeleteIndexIfExists()
.indexClient
// Getting the name of the index from the index definition
const indexName: string = hotelIndexDefinition.name;
console.log('Checking if index exists...');
await deleteIndexIfExists(indexClient, indexName);
Ezután készen állunk az index metódussal való létrehozására createIndex()
.
console.log('Creating index...');
let index = await indexClient.createIndex(hotelIndexDefinition);
console.log(`Index named ${index.name} has been created.`);
Dokumentumok betöltése
Az Azure AI Searchben a dokumentumok olyan adatstruktúrák, amelyek egyaránt bemenetek az indexeléshez és a lekérdezésekből származó kimenetekhez. Ezeket az adatokat leküldheti az indexbe, vagy használhat indexelőt. Ebben az esetben programozott módon leküldjük a dokumentumokat az indexbe.
A dokumentumbemenetek lehetnek egy adatbázis sorai, blobok a Blob Storage-ban, vagy a mintában szereplő JSON-dokumentumok a lemezen. Letöltheti hotels.json , vagy létrehozhat saját hotels.json fájlt a következő tartalommal:
Az indexDefinitionhez hasonlóan a index.ts tetején is importálnunk hotels.json
kell, hogy az adatok elérhetők legyenek a fő függvényünkben.
import hotelData from './hotels.json';
interface Hotel {
HotelId: string;
HotelName: string;
Description: string;
Description_fr: string;
Category: string;
Tags: string[];
ParkingIncluded: string | boolean;
LastRenovationDate: string;
Rating: number;
Address: {
StreetAddress: string;
City: string;
StateProvince: string;
PostalCode: string;
};
};
const hotels: Hotel[] = hotelData["value"];
Ha adatokat szeretne indexelni a keresési indexbe, létre kell hoznunk egy SearchClient
. Bár az SearchIndexClient
indexek létrehozására és kezelésére szolgál, a SearchClient
dokumentumok feltöltésére és az index lekérdezésére szolgál.
Kétféleképpen hozhat létre .SearchClient
Az első lehetőség a nulláról történő létrehozás SearchClient
:
const searchClient = new SearchClient<Hotel>(endpoint, indexName, new AzureKeyCredential(apiKey));
Másik lehetőségként a getSearchClient()
következő metódus SearchIndexClient
használatával is létrehozhatja a következőt SearchClient
:
const searchClient = indexClient.getSearchClient<Hotel>(indexName);
Az ügyfél definiálása után töltse fel a dokumentumokat a keresési indexbe. Ebben az esetben a metódust mergeOrUploadDocuments()
használjuk, amely feltölti a dokumentumokat, vagy egyesíti őket egy meglévő dokumentummal, ha már létezik ugyanazzal a kulccsal rendelkező dokumentum. Ezután ellenőrizze, hogy a művelet sikeres volt-e, mert legalább az első dokumentum létezik.
console.log("Uploading documents...");
const indexDocumentsResult = await searchClient.mergeOrUploadDocuments(hotels);
console.log(`Index operations succeeded: ${JSON.stringify(indexDocumentsResult.results[0].succeeded)}`);
Futtassa újra a programot a következővel tsc && node index.ts
: . Az 1. lépésben látottaktól kissé eltérő üzenetkészletnek kell megjelennie. Ezúttal az index létezik , és látnia kell egy, a törlésről szóló üzenetet, mielőtt az alkalmazás létrehozza az új indexet, és közzétennénk az adatokat.
Mielőtt a következő lépésben futtatnánk a lekérdezéseket, definiáljon egy függvényt, hogy a program egy másodpercig várakozzon. Ez csak tesztelési/demó céljából történik, hogy az indexelés befejeződjön, és hogy a dokumentumok elérhetők legyenek az indexben a lekérdezéseinkhez.
function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
Ha azt szeretné, hogy a program egy másodpercig várjon, hívja meg a függvényt sleep
:
sleep(1000);
Keresés az indexekben
Egy index létrehozásával és a feltöltött dokumentumokkal lekérdezéseket küldhet az indexnek. Ebben a szakaszban öt különböző lekérdezést küldünk a keresési indexbe, hogy bemutassuk az Ön számára elérhető különböző lekérdezési funkciókat.
A lekérdezések egy sendQueries()
függvényben vannak megírva, amelyet a fő függvényben hívunk meg az alábbiak szerint:
await sendQueries(searchClient);
A rendszer a lekérdezéseket a search()
következő módszerrel küldi searchClient
el: . Az első paraméter a keresési szöveg, a második pedig a keresési beállításokat adja meg.
1. lekérdezési példa
Az első lekérdezés minden *
kereséssel egyenértékű, és az index három mezőjét választja ki. Ajánlott csak a szükséges mezőket használni select
, mert a szükségtelen adatok visszakérése késést okozhat a lekérdezésekben.
Ennek searchOptions
a lekérdezésnek a értéke is be van includeTotalCount
állítva true
, amely a talált találatok számát adja vissza.
async function sendQueries(
searchClient: SearchClient<Hotel>
): Promise<void> {
// Query 1
console.log('Query #1 - search everything:');
const selectFields: SearchFieldArray<Hotel> = [
"HotelId",
"HotelName",
"Rating",
];
const searchOptions1 = {
includeTotalCount: true,
select: selectFields
};
let searchResults = await searchClient.search("*", searchOptions1);
for await (const result of searchResults.results) {
console.log(`${JSON.stringify(result.document)}`);
}
console.log(`Result count: ${searchResults.count}`);
// remaining queries go here
}
Az alább ismertetett többi lekérdezést is hozzá kell adni a sendQueries()
függvényhez. Itt külön vannak elválasztva az olvashatóság érdekében.
2. lekérdezési példa
A következő lekérdezésben megadjuk a keresési kifejezést "wifi"
, és egy szűrőt is belefoglalunk, amely csak olyan eredményeket ad vissza, ahol az állapot egyenlő 'FL'
. Az eredményeket a szálloda is rendezi Rating
.
console.log('Query #2 - search with filter, orderBy, and select:');
let state = 'FL';
const searchOptions2 = {
filter: odata`Address/StateProvince eq ${state}`,
orderBy: ["Rating desc"],
select: selectFields
};
searchResults = await searchClient.search("wifi", searchOptions2);
for await (const result of searchResults.results) {
console.log(`${JSON.stringify(result.document)}`);
}
3. lekérdezési példa
Ezután a keresés egyetlen kereshető mezőre korlátozódik a searchFields
paraméter használatával. Ez a megközelítés nagyszerű lehetőség arra, hogy hatékonyabbá tegye a lekérdezést, ha tudja, hogy csak bizonyos mezőkben lévő egyezések érdeklik.
console.log('Query #3 - limit searchFields:');
const searchOptions3 = {
select: selectFields,
searchFields: ["HotelName"] as const
};
searchResults = await searchClient.search("Sublime Palace", searchOptions3);
for await (const result of searchResults.results) {
console.log(`${JSON.stringify(result.document)}`);
}
4. lekérdezési példa
Egy másik gyakori lehetőség a lekérdezésbe való belefoglalás.facets
Az aspektusok lehetővé teszik, hogy ön által irányított részletezéseket biztosítson a felhasználói felületen található eredményekből. Az eredmények az eredménypanelen jelölőnégyzetekké alakíthatók.
console.log('Query #4 - limit searchFields and use facets:');
const searchOptions4 = {
facets: ["Category"],
select: selectFields,
searchFields: ["HotelName"] as const
};
searchResults = await searchClient.search("*", searchOptions4);
for await (const result of searchResults.results) {
console.log(`${JSON.stringify(result.document)}`);
}
5. lekérdezési példa
A végső lekérdezés a getDocument()
searchClient
. Így hatékonyan lekérhet egy dokumentumot a kulcsával.
console.log('Query #5 - Lookup document:');
let documentResult = await searchClient.getDocument('3')
console.log(`HotelId: ${documentResult.HotelId}; HotelName: ${documentResult.HotelName}`)
Lekérdezések összegzése
Az előző lekérdezések több módon is egyeztetik a kifejezéseket a lekérdezésekben: teljes szöveges keresés, szűrők és automatikus kiegészítés.
A metódussal searchClient.search
teljes szöveges keresést és szűrőket hajtunk végre. A keresési lekérdezések átadhatók a sztringben searchText
, míg egy szűrőkifejezés átadható az filter
SearchOptions
osztály tulajdonságában. Keresés nélküli szűréshez egyszerűen adja meg a "*" értéket a searchText
search
metódus paraméteréhez. Ha szűrés nélkül szeretne keresni, hagyja meg a filter
tulajdonságot, vagy egyáltalán ne adja át a példányt SearchOptions
.
Erőforrások törlése
Ha a saját előfizetésében dolgozik, érdemes az egyes projektek végén eldöntenie, hogy szüksége lesz-e még a létrehozott erőforrásokra. A továbbra is futó erőforrások költségekkel járhatnak. Az erőforrásokat törölheti egyesével, vagy az erőforráscsoport törlésével eltávolíthatja a benne lévő összes erőforrást is.
Az erőforrásokat az Azure Portalon, a bal oldali navigációs panel Minden erőforrás vagy erőforráscsoport hivatkozásával keresheti meg és kezelheti.
Ha ingyenes szolgáltatást használ, ne feledje, hogy három indexre, indexelőre és adatforrásra korlátozódik. Az Azure Portalon törölheti az egyes elemeket, hogy a korlát alatt maradjon.
Következő lépés
Ebben a rövid útmutatóban feladatokat dolgozott ki egy index létrehozásához, dokumentumokba való betöltéséhez és lekérdezések futtatásához. Különböző szakaszokban billentyűparancsokkal egyszerűsítettük a kódot az olvashatóság és a megértés érdekében. Most, hogy megismerte az alapfogalmakat, próbáljon ki egy oktatóanyagot, amely meghívja az Azure AI Search API-kat egy webalkalmazásban.