Sonraki adım için bir programlama dili seçin. Azure.Search.Documents istemci kitaplıkları .NET, Python, Java ve JavaScript/Typescript için Azure SDK'larında kullanılabilir.
Arama dizini oluşturmak, yüklemek ve sorgulamak için Azure.Search.Documents istemci kitaplığını kullanarak bir konsol uygulaması oluşturun.
Alternatif olarak, tamamlanmış bir projeyle başlamak için kaynak kodu indirebilir veya kendi projenizi oluşturmak için bu adımları izleyebilirsiniz.
Ortamınızı ayarlama
Visual Studio'yu başlatın ve konsol uygulaması için yeni bir proje oluşturun.
Araçlar>NuGet Paket Yöneticisi Çözüm için NuGet Paketlerini Yönet... seçeneğini belirleyin.
Göz At'ı seçin.
Azure.Search.Documents paketini arayın ve sürüm 11.0 veya üzerini seçin.
Derlemeyi projenize ve çözümünüze eklemek için Yükle'yi seçin.
Arama istemcisi oluşturma
Program.cs ad alanını olarak AzureSearch.SDK.Quickstart.v11
değiştirin ve ardından aşağıdaki using
yönergeleri ekleyin.
using Azure;
using Azure.Search.Documents;
using Azure.Search.Documents.Indexes;
using Azure.Search.Documents.Indexes.Models;
using Azure.Search.Documents.Models;
İki istemci oluşturmak için aşağıdaki kodu kopyalayın. SearchIndexClient dizini oluşturur ve SearchClient var olan bir dizini yükler ve sorgular. Hem hizmet uç noktası hem de oluşturma/silme haklarıyla kimlik doğrulaması için bir yönetici API anahtarı gerekir.
Kod sizin için URI'yi oluşturacağından, özelliğinde serviceName
yalnızca arama hizmeti adını belirtin.
static void Main(string[] args)
{
string serviceName = "<your-search-service-name>";
string apiKey = "<your-search-service-admin-api-key>";
string indexName = "hotels-quickstart";
// Create a SearchIndexClient to send create/delete index commands
Uri serviceEndpoint = new Uri($"https://{serviceName}.search.windows.net/");
AzureKeyCredential credential = new AzureKeyCredential(apiKey);
SearchIndexClient adminClient = new SearchIndexClient(serviceEndpoint, credential);
// Create a SearchClient to load and query documents
SearchClient srchclient = new SearchClient(serviceEndpoint, indexName, credential);
. . .
}
Dizin oluşturma
Bu hızlı başlangıçta, otel verileriyle yükleyip sorgular yürütdüğünüz bir Hotels dizini oluşturacaksınız. Bu adımda, dizindeki alanları tanımlayın. Her alan tanımı, alanın nasıl kullanıldığını belirleyen bir ad, veri türü ve öznitelikler içerir.
Bu örnekte, kolaylık ve okunabilirlik için Azure.Search.Documents kitaplığının zaman uyumlu yöntemleri kullanılır. Ancak üretim senaryolarında uygulamanızı ölçeklenebilir ve duyarlı tutmak için zaman uyumsuz yöntemler kullanmanız gerekir. Örneğin, CreateIndex yerine CreateIndexAsync kullanabilirsiniz.
Projenize boş bir sınıf tanımı ekleyin: Hotel.cs
Otel belgesinin yapısını tanımlamak için aşağıdaki kodu Hotel.cs kopyalayın. Alandaki öznitelikler, uygulamada nasıl kullanıldığını belirler. Örneğin, IsFilterable
özniteliği bir filtre ifadesini destekleyen her alana atanmalıdır.
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; }
}
}
Azure.Search.Documents istemci kitaplığında, alan tanımlarını kolaylaştırmak için SearchableField ve SimpleField kullanabilirsiniz. Her ikisi de SearchField'in türevleridir ve kodunuzu basitleştirebilir:
SimpleField
herhangi bir veri türü olabilir, her zaman aranamaz (tam metin arama sorguları için yoksayılır) ve alınabilir (gizli değildir). Diğer öznitelikler varsayılan olarak kapalıdır, ancak etkinleştirilebilir. Belge kimlikleri veya yalnızca filtrelerde, modellerde veya puanlama profillerinde kullanılan alanlar için kullanabilirsiniz SimpleField
. Bu durumda, belge kimliği gibi IsKey = true
senaryo için gerekli olan öznitelikleri uyguladığınıza emin olun. Daha fazla bilgi için bkz . kaynak kodunda SimpleFieldAttribute.cs .
SearchableField
bir dize olmalıdır ve her zaman aranabilir ve alınabilir. Diğer öznitelikler varsayılan olarak kapalıdır, ancak etkinleştirilebilir. Bu alan türü aranabilir olduğundan, eş anlamlıları ve çözümleyici özelliklerinin tam tamamlayıcısını destekler. Daha fazla bilgi için kaynak kodundaki SearchableFieldAttribute.cs bakın.
İster temel SearchField
API'yi ister yardımcı modellerden birini kullanın, filtre, model ve sıralama özniteliklerini açıkça etkinleştirmeniz gerekir. Örneğin, önceki örnekte gösterildiği gibi IsFilterable, IsSortable ve IsFacetable açıkça ilişkilendirilmelidir.
Projenize ikinci bir boş sınıf tanımı ekleyin: Address.cs. Aşağıdaki kodu sınıfına kopyalayın.
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; }
}
}
İki sınıf daha oluşturun: geçersiz kılmalar için ToString()
Hotel.Methods.cs ve Address.Methods.cs. Bu sınıflar, konsol çıkışında arama sonuçlarını işlemek için kullanılır. Bu sınıfların içeriği bu makalede sağlanmamıştır, ancak GitHub'daki dosyalardan kodu kopyalayabilirsiniz.
Program.cs bir SearchIndex nesnesi oluşturun ve ardından arama hizmetinizdeki dizini ifade etmek için CreateIndex yöntemini çağırın. Dizin ayrıca, belirtilen alanlarda otomatik tamamlamayı etkinleştirmek için bir SearchSuggester içerir.
// Create hotels-quickstart index
private static void CreateIndex(string indexName, SearchIndexClient adminClient)
{
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);
adminClient.CreateOrUpdateIndex(definition);
}
Belge yükleme
Azure AI Search, hizmette depolanan içerik üzerinde aramalar. Bu adımda, yeni oluşturduğunuz otel dizinine uygun JSON belgelerini yükleyeceksiniz.
Azure AI Search'te arama belgeleri hem dizin oluşturmaya giriş hem de sorgulardan alınan çıkışlar olan veri yapılarıdır. Dış veri kaynağından elde edilen belge girişleri veritabanındaki satırlar, Blob depolamadaki bloblar veya diskteki JSON belgeleri olabilir. Bu örnekte bir kısayol kullanıyoruz ve kodun kendisine dört otel için JSON belgeleri ekliyoruz.
Belgeleri karşıya yüklerken IndexDocumentsBatch nesnesi kullanmanız gerekir. NesneIndexDocumentsBatch
, her biri bir belge ve Azure AI Search'e gerçekleştirilecek eylemi (karşıya yükleme, birleştirme, silme ve birleştirmeOrUpload) söyleyen bir özellik içeren bir Eylemler koleksiyonu içerir.
Program.cs bir dizi belge ve dizin eylemi oluşturun ve diziyi öğesine IndexDocumentsBatch
geçirin. Aşağıdaki belgeler, otel sınıfı tarafından tanımlanan hotels-quickstart dizinine uygundur.
// 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"
}
}),
IndexDocumentsAction.Upload(
new Hotel()
{
HotelId = "2",
HotelName = "Old Century 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.",
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 = "Gastronomic 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 Palace 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.",
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.",
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}");
}
}
IndexDocumentsBatch nesnesini başlatıldıktan sonra, SearchClient nesnenizde IndexDocuments'ı çağırarak dizine gönderebilirsiniz.
öğesine aşağıdaki satırları Main()
ekleyin. Belgeleri yükleme işlemi SearchClient kullanılarak yapılır, ancak işlem genellikle SearchIndexClient ile ilişkilendirilmiş olan hizmet üzerinde yönetici hakları da gerektirir. Bu işlemi ayarlamanın bir yolu SearchClient'ı SearchIndexClient
aracılığıyla almaktır (adminClient
bu örnekte).
SearchClient ingesterClient = adminClient.GetSearchClient(indexName);
// Load documents
Console.WriteLine("{0}", "Uploading documents...\n");
UploadDocuments(ingesterClient);
Bu, tüm komutları sıralı olarak çalıştıran bir konsol uygulaması olduğundan, dizin oluşturma ve sorgular arasında 2 saniyelik bekleme süresi ekleyin.
// 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);
2 saniyelik gecikme, sorgular yürütülmeden önce tüm belgelerin dizine alınabilmesi için zaman uyumsuz olan dizin oluşturmayı telafi eder. Gecikmeli kodlama genellikle yalnızca tanıtımlarda, testlerde ve örnek uygulamalarda gereklidir.
Dizin arama
İlk belge dizine alınır başlatılmaz sorgu sonuçlarını alabilirsiniz, ancak dizininizin gerçek testi tüm belgeler dizine alınana kadar beklemelidir.
Bu bölüm iki işlev parçası ekler: sorgu mantığı ve sonuçlar. Sorgular için Search yöntemini kullanın. Bu yöntem arama metnini (sorgu dizesi) ve diğer seçenekleri alır.
SearchResults sınıfı sonuçları temsil eder.
Program.cs'da, arama sonuçlarını konsola yazdıran bir WriteDocuments
yöntem oluşturun.
// 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();
}
Sorguları yürütmek ve sonuçları döndürmek için bir RunQueries
yöntem oluşturun. Sonuçlar Otel nesneleridir. Bu örnek yöntem imzasını ve ilk sorguyu gösterir. Bu sorgu, belgeden seçilen alanları kullanarak sonucu oluşturmanıza olanak tanıyan Select parametresini gösterir.
// Run queries, use WriteDocuments to print output
private static void RunQueries(SearchClient srchclient)
{
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 = srchclient.Search<Hotel>("*", options);
WriteDocuments(response);
İkinci sorguda terimi arayın, Derecelendirmenin 4'ten büyük olduğu belgeleri seçen bir filtre ekleyin ve ardından Azalan düzende Derecelendirmeye göre sıralayın. Filtre, bir dizindeki IsFilterable alanları üzerinden değerlendirilen bir boole ifadesidir. Filtre sorguları değerleri içerir veya hariç tutar. Bu nedenle, filtre sorgusuyla ilişkilendirilmiş bir ilgi puanı yoktur.
// 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 = srchclient.Search<Hotel>("hotels", options);
WriteDocuments(response);
Üçüncü sorgu, bir tam metin arama işleminin kapsamını belirli alanlara göre ayarlamak için kullanılan öğesini gösterir 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 = srchclient.Search<Hotel>("pool", options);
WriteDocuments(response);
Dördüncü sorgu, modelli bir gezinti yapısını yapılandırmak için kullanılabilen öğesini gösterir facets
.
// 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 = srchclient.Search<Hotel>("*", options);
WriteDocuments(response);
Beşinci sorguda belirli bir belgeyi döndürür. Belge arama, sonuç kümesindeki olaya tipik bir yanıttır OnClick
.
// Query 5
Console.WriteLine("Query #5: Look up a specific document...\n");
Response<Hotel> lookupResponse;
lookupResponse = srchclient.GetDocument<Hotel>("3");
Console.WriteLine(lookupResponse.Value.HotelId);
Son sorgu otomatik tamamlama söz dizimini gösterir ve dizinde tanımladığınız önericisi ile ilişkili sourceFields içinde iki olası eşleşmeye çözümleyen sa'nın kısmi kullanıcı girişinin benzetimini gösterir.
// Query 6
Console.WriteLine("Query #6: Call Autocomplete on HotelName that starts with 'sa'...\n");
var autoresponse = srchclient.Autocomplete("sa", "sg");
WriteDocuments(autoresponse);
Add RunQueries
to Main()
.
// Call the RunQueries method to invoke a series of queries
Console.WriteLine("Starting queries...\n");
RunQueries(srchclient);
// End the program
Console.WriteLine("{0}", "Complete. Press any key to end this program...\n");
Console.ReadKey();
Önceki sorgular sorguda terimleri eşleştirmenin birden çok yolunu gösterir: tam metin araması, filtreler ve otomatik tamamlama.
Tam metin araması ve filtreler SearchClient.Search yöntemi kullanılarak gerçekleştirilir. Arama sorgusu dizede searchText
geçirilebilirken SearchOptions sınıfının Filter özelliğinde bir filtre ifadesi geçirilebilir. Arama yapmadan filtrelemek için Search yönteminin searchText
parametresini geçirmesi "*"
gerekir. Filtreleme olmadan arama yapmak için özelliğini ayarsız bırakın Filter
veya bir SearchOptions
örneği hiç geçirmeyin.
Programı çalıştırma
Uygulamayı yeniden derlemek ve programı tamamen çalıştırmak için F5 tuşuna basın.
Çıktı, sorgu bilgilerinin ve sonuçların eklenmesiyle birlikte Console.WriteLine'dan gelen iletileri içerir.
Arama dizini oluşturmak, yüklemek ve sorgulamak için Bir Jupyter not defteri ve Python için Azure SDK'daki azure-search-documents kitaplığını kullanın.
Alternatif olarak, tamamlanmış bir not defterini indirip çalıştırabilirsiniz.
Ortamınızı ayarlama
Python uzantısıyla Visual Studio Code veya Python 3.10 veya üzeri ile eşdeğer bir IDE kullanın.
Bu hızlı başlangıç için bir sanal ortam öneririz:
Visual Studio Code’u başlatın.
Komut Paleti'ni açın (Ctrl+Shift+P).
Python: Ortam Oluştur'u arayın.
Venv.
seçeneğini belirleyin
Bir Python yorumlayıcısı seçin. Sürüm 3.10 veya üzerini seçin.
Kurulumu bir dakika sürebilir. Sorunlarla karşılaşırsanız bkz . VS Code'da Python ortamları.
Paketleri yükleme ve değişkenleri ayarlama
Azure-search-documents dahil olmak üzere paketleri yükleyin.
! pip install azure-search-documents==11.6.0b1 --quiet
! pip install azure-identity --quiet
! pip install python-dotenv --quiet
Hizmetiniz için uç nokta ve API anahtarını sağlayın:
search_endpoint: str = "PUT-YOUR-SEARCH-SERVICE-ENDPOINT-HERE"
search_api_key: str = "PUT-YOUR-SEARCH-SERVICE-ADMIN-API-KEY-HERE"
index_name: str = "hotels-quickstart"
Dizin oluşturma
from azure.core.credentials import AzureKeyCredential
credential = AzureKeyCredential(search_api_key)
from azure.search.documents.indexes import SearchIndexClient
from azure.search.documents import SearchClient
from azure.search.documents.indexes.models import (
ComplexField,
SimpleField,
SearchFieldDataType,
SearchableField,
SearchIndex
)
# Create a search schema
index_client = SearchIndexClient(
endpoint=search_endpoint, credential=credential)
fields = [
SimpleField(name="HotelId", type=SearchFieldDataType.String, key=True),
SearchableField(name="HotelName", type=SearchFieldDataType.String, sortable=True),
SearchableField(name="Description", type=SearchFieldDataType.String, analyzer_name="en.lucene"),
SearchableField(name="Description_fr", type=SearchFieldDataType.String, analyzer_name="fr.lucene"),
SearchableField(name="Category", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),
SearchableField(name="Tags", collection=True, type=SearchFieldDataType.String, facetable=True, filterable=True),
SimpleField(name="ParkingIncluded", type=SearchFieldDataType.Boolean, facetable=True, filterable=True, sortable=True),
SimpleField(name="LastRenovationDate", type=SearchFieldDataType.DateTimeOffset, facetable=True, filterable=True, sortable=True),
SimpleField(name="Rating", type=SearchFieldDataType.Double, facetable=True, filterable=True, sortable=True),
ComplexField(name="Address", fields=[
SearchableField(name="StreetAddress", type=SearchFieldDataType.String),
SearchableField(name="City", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),
SearchableField(name="StateProvince", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),
SearchableField(name="PostalCode", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),
SearchableField(name="Country", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),
])
]
scoring_profiles = []
suggester = [{'name': 'sg', 'source_fields': ['Tags', 'Address/City', 'Address/Country']}]
# Create the search index
index = SearchIndex(name=index_name, fields=fields, suggesters=suggester, scoring_profiles=scoring_profiles)
result = index_client.create_or_update_index(index)
print(f' {result.name} created')
Belge yükü oluşturma
İşlem türü için karşıya yükleme veya birleştirme ve karşıya yükleme gibi bir dizin eylemi kullanın. Belgeler GitHub'daki HotelsData örneğinden kaynaklanır.
# Create a documents payload
documents = [
{
"@search.action": "upload",
"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.",
"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.60,
"Address": {
"StreetAddress": "677 5th Ave",
"City": "New York",
"StateProvince": "NY",
"PostalCode": "10022",
"Country": "USA"
}
},
{
"@search.action": "upload",
"HotelId": "2",
"HotelName": "Old Century 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.",
"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.60,
"Address": {
"StreetAddress": "140 University Town Center Dr",
"City": "Sarasota",
"StateProvince": "FL",
"PostalCode": "34243",
"Country": "USA"
}
},
{
"@search.action": "upload",
"HotelId": "3",
"HotelName": "Gastronomic 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.80,
"Address": {
"StreetAddress": "3393 Peachtree Rd",
"City": "Atlanta",
"StateProvince": "GA",
"PostalCode": "30326",
"Country": "USA"
}
},
{
"@search.action": "upload",
"HotelId": "4",
"HotelName": "Sublime Palace 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.",
"Description_fr": "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.",
"Category": "Boutique",
"Tags": [ "concierge", "view", "24-hour front desk service" ],
"ParkingIncluded": "true",
"LastRenovationDate": "1960-02-06T00:00:00Z",
"Rating": 4.60,
"Address": {
"StreetAddress": "7400 San Pedro Ave",
"City": "San Antonio",
"StateProvince": "TX",
"PostalCode": "78216",
"Country": "USA"
}
}
]
Belgeleri karşıya yükle
# Upload documents to the index
search_client = SearchClient(endpoint=search_endpoint,
index_name=index_name,
credential=credential)
try:
result = search_client.upload_documents(documents=documents)
print("Upload of new document succeeded: {}".format(result[0].succeeded))
except Exception as ex:
print (ex.message)
index_client = SearchIndexClient(
endpoint=search_endpoint, credential=credential)
İlk sorgunuzu çalıştırma
search.client sınıfının arama yöntemini kullanın.
Bu örnek boş bir arama yürütür (search=*
) ve rastgele belgelerden oluşan bir liste (arama puanı = 1,0) döndürür. Ölçüt olmadığından, tüm belgeler sonuçlara eklenir.
# Run an empty query (returns selected fields, all documents)
results = search_client.search(query_type='simple',
search_text="*" ,
select='HotelName,Description',
include_total_count=True)
print ('Total Documents Matching Query:', results.get_count())
for result in results:
print(result["@search.score"])
print(result["HotelName"])
print(f"Description: {result['Description']}")
Terim sorgusu çalıştırma
Sonraki sorgu, arama ifadesine ("wifi") tüm terimleri ekler. Bu sorgu, sonuçların deyiminde yalnızca bu alanları içerdiğini select
belirtir. Geri gelen alanları sınırlamak, kablo üzerinden geri gönderilen veri miktarını en aza indirir ve arama gecikme süresini azaltır.
results = search_client.search(query_type='simple',
search_text="wifi" ,
select='HotelName,Description,Tags',
include_total_count=True)
print ('Total Documents Matching Query:', results.get_count())
for result in results:
print(result["@search.score"])
print(result["HotelName"])
print(f"Description: {result['Description']}")
Filtre ekleyin
Yalnızca derecelendirmesi dörtten büyük olan otelleri azalan düzende sıralanmış olarak döndüren bir filtre ifadesi ekleyin.
# Add a filter
results = search_client.search(
search_text="hotels",
select='HotelId,HotelName,Rating',
filter='Rating gt 4',
order_by='Rating desc')
for result in results:
print("{}: {} - {} rating".format(result["HotelId"], result["HotelName"], result["Rating"]))
Alan kapsamı ekleme
Kapsam sorgusu yürütmeye belirli alanlara ekleyin search_fields
.
# Add search_fields to scope query matching to the HotelName field
results = search_client.search(
search_text="sublime",
search_fields=['HotelName'],
select='HotelId,HotelName')
for result in results:
print("{}: {}".format(result["HotelId"], result["HotelName"]))
Model ekleme
Model, arama sonuçlarında bulunan pozitif eşleşmeler için oluşturulur. Sıfır eşleşme yok. Arama sonuçları wifi terimini içermiyorsa, wifi modelli gezinti yapısında görünmez.
# Return facets
results = search_client.search(search_text="*", facets=["Category"])
facets = results.get_facets()
for facet in facets["Category"]:
print(" {}".format(facet))
Belge arama
Bir belgeyi anahtarına göre döndürür. Bu işlem, kullanıcı arama sonucundaki bir öğeyi seçtiğinde detaylandırma sağlamak istiyorsanız kullanışlıdır.
# Look up a specific document by ID
result = search_client.get_document(key="3")
print("Details for hotel '3' are:")
print("Name: {}".format(result["HotelName"]))
print("Rating: {}".format(result["Rating"]))
print("Category: {}".format(result["Category"]))
Otomatik tamamlama ekleme
Otomatik tamamlama, kullanıcı arama kutusuna yazarken olası eşleşmeler sağlayabilir.
Otomatik Tamamlama, hangi alanların öneri istekleriyle olası eşleşmeler içerdiğini bilmek için bir öneri oluşturucu (sg
) kullanır. Bu hızlı başlangıçta, bu alanlar Tags
, , Address/City
Address/Country
.
Otomatik tamamlama benzetimi yapmak için sa harflerini kısmi dize olarak geçirin. SearchClient'ın otomatik tamamlama yöntemi olası terim eşleşmelerini geri gönderir.
# Autocomplete a query
search_suggestion = 'sa'
results = search_client.autocomplete(
search_text=search_suggestion,
suggester_name="sg",
mode='twoTerms')
print("Autocomplete for:", search_suggestion)
for result in results:
print (result['text'])
Arama dizini oluşturmak, yüklemek ve sorgulamak için Azure.Search.Documents kitaplığını kullanarak bir Java konsol uygulaması oluşturun.
Alternatif olarak, tamamlanmış bir projeyle başlamak için kaynak kodu indirebilir veya kendi projenizi oluşturmak için bu adımları izleyebilirsiniz.
Ortamınızı ayarlama
Bu hızlı başlangıcı oluşturmak için aşağıdaki araçları kullanın.
Proje oluşturma
Visual Studio Code’u başlatın.
Ctrl+Shift+P tuşlarını kullanarak Komut Paleti'ni açın. Java Projesi Oluştur'u arayın.
Maven'ı seçin.
maven-archetype-quickstart öğesini seçin.
Şu anda 1.4 olan en son sürümü seçin.
Grup kimliği olarak azure.search.sample girin.
Yapıt kimliği olarak azuresearchquickstart girin.
Projenin oluşturulacağı klasörü seçin.
Tümleşik terminalde proje oluşturmayı tamamlayın. "1.0-SNAPSHOT" için varsayılanı kabul etmek için Enter tuşuna basın ve ardından projenizin özelliklerini onaylamak için "y" yazın.
Projeyi oluşturduğunuz klasörü açın.
Maven bağımlılıklarını belirtme
pom.xml dosyasını açın ve aşağıdaki bağımlılıkları ekleyin.
<dependencies>
<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>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
Derleyici Java sürümünü 11 olarak değiştirin.
<maven.compiler.source>1.11</maven.compiler.source>
<maven.compiler.target>1.11</maven.compiler.target>
Arama istemcisi oluşturma
App
src, main, java, azure, search, sample altında sınıfını açın. Aşağıdaki içeri aktarma yönergelerini ekleyin.
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.credential.AzureKeyCredential;
import com.azure.core.util.Context;
import com.azure.search.documents.SearchClient;
import com.azure.search.documents.SearchClientBuilder;
import com.azure.search.documents.models.SearchOptions;
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.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;
Aşağıdaki örnekte, arama hizmeti adı için yer tutucular, oluşturma ve silme izinleri veren yönetici API anahtarı ve dizin adı yer almaktadır. Üç yer tutucu için de geçerli değerleri değiştirin. İki istemci oluşturma: SearchIndexClient dizini oluşturur ve SearchClient var olan bir dizini yükler ve sorgular. Hem hizmet uç noktası hem de oluşturma ve silme haklarıyla kimlik doğrulaması için bir yönetici API anahtarı gerekir.
public static void main(String[] args) {
var searchServiceEndpoint = "<YOUR-SEARCH-SERVICE-URL>";
var adminKey = new AzureKeyCredential("<YOUR-SEARCH-SERVICE-ADMIN-KEY>");
String indexName = "<YOUR-SEARCH-INDEX-NAME>";
SearchIndexClient searchIndexClient = new SearchIndexClientBuilder()
.endpoint(searchServiceEndpoint)
.credential(adminKey)
.buildClient();
SearchClient searchClient = new SearchClientBuilder()
.endpoint(searchServiceEndpoint)
.credential(adminKey)
.indexName(indexName)
.buildClient();
}
Dizin oluşturma
Bu hızlı başlangıçta, otel verileriyle yükleyip sorgular yürütdüğünüz bir Hotels dizini oluşturacaksınız. Bu adımda, dizindeki alanları tanımlayın. Her alan tanımı, alanın nasıl kullanıldığını belirleyen bir ad, veri türü ve öznitelikler içerir.
Bu örnekte, kolaylık ve okunabilirlik için azure-search-documents kitaplığının zaman uyumlu yöntemleri kullanılır. Ancak üretim senaryolarında uygulamanızı ölçeklenebilir ve duyarlı tutmak için zaman uyumsuz yöntemler kullanmanız gerekir. Örneğin, SearchClient yerine SearchAsyncClient kullanabilirsiniz.
Projenize boş bir sınıf tanımı ekleyin: Hotel.java
Bir otel belgesinin yapısını tanımlamak için aşağıdaki kodu içine Hotel.java
kopyalayın. Alandaki öznitelikler, uygulamada nasıl kullanıldığını belirler. Örneğin, Filtrelenebilir ek açıklaması bir filtre ifadesini destekleyen her alana atanmalıdır
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package azure.search.sample;
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 "";
}
}
}
Azure.Search.Documents istemci kitaplığında, alan tanımlarını kolaylaştırmak için SearchableField ve SimpleField kullanabilirsiniz.
SimpleField
herhangi bir veri türü olabilir, her zaman aranamaz (tam metin arama sorguları için yoksayılır) ve alınabilir (gizli değildir). Diğer öznitelikler varsayılan olarak kapalıdır, ancak etkinleştirilebilir. Belge kimlikleri veya yalnızca filtrelerde, modellerde veya puanlama profillerinde kullanılan alanlar için SimpleField kullanabilirsiniz. Bu durumda, belge kimliği için IsKey = true gibi senaryo için gerekli olan öznitelikleri uyguladığınıza emin olun.
SearchableField
bir dize olmalıdır ve her zaman aranabilir ve alınabilir. Diğer öznitelikler varsayılan olarak kapalıdır, ancak etkinleştirilebilir. Bu alan türü aranabilir olduğundan, eş anlamlıları ve çözümleyici özelliklerinin tam tamamlayıcısını destekler.
İster temel SearchField
API'yi ister yardımcı modellerden birini kullanın, filtre, model ve sıralama özniteliklerini açıkça etkinleştirmeniz gerekir. Örneğin, isFilterable
önceki örnekte gösterildiği gibi , isSortable
ve isFacetable
açıkça ilişkilendirilmelidir.
Projenize ikinci bir boş sınıf tanımı ekleyin: Address.java
. Aşağıdaki kodu sınıfına kopyalayın.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
package azure.search.sample;
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;
}
içindeApp.java
, yönteminde main
bir SearchIndex
nesne oluşturun ve ardından arama hizmetinizde dizini oluşturmak için yöntemini çağırıncreateOrUpdateIndex
. Dizin ayrıca belirtilen alanlarda otomatik tamamlamayı etkinleştirmek için bir SearchSuggester
içerir.
// Create Search Index for Hotel model
searchIndexClient.createOrUpdateIndex(
new SearchIndex(indexName, SearchIndexClient.buildSearchFields(Hotel.class, null))
.setSuggesters(new SearchSuggester("sg", Arrays.asList("HotelName"))));
Belge yükleme
Azure AI Search, hizmette depolanan içerik üzerinde aramalar. Bu adımda, yeni oluşturduğunuz otel dizinine uygun JSON belgelerini yükleyeceksiniz.
Azure AI Search'te arama belgeleri hem dizin oluşturmaya giriş hem de sorgulardan alınan çıkışlar olan veri yapılarıdır. Dış veri kaynağından elde edilen belge girişleri veritabanındaki satırlar, Blob depolamadaki bloblar veya diskteki JSON belgeleri olabilir. Bu örnekte bir kısayol kullanıyoruz ve kodun kendisine dört otel için JSON belgeleri ekliyoruz.
Belgeleri karşıya yüklerken IndexDocumentsBatch nesnesi kullanmanız gerekir. Bir IndexDocumentsBatch
nesne, her biri Azure AI Search'e hangi eylemin gerçekleştirileceği (karşıya yükleme, birleştirme, silme ve birleştirmeOrUpload) söyleyen bir belge ve özellik içeren bir IndexActions koleksiyonu içerir.
içinde App.java
, belgeler ve dizin eylemleri oluşturun ve sonra bunları öğesine IndexDocumentsBatch
geçirin. Aşağıdaki belgeler, otel sınıfı tarafından tanımlanan hotels-quickstart dizinine uygundur.
// 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");
}
}
Nesneyi başlatıldıktan IndexDocumentsBatch
sonra, nesnenizde SearchClient
indexDocuments'ı çağırarak dizine gönderebilirsiniz.
öğesine aşağıdaki satırları Main()
ekleyin. Belgeleri yükleme işlemi kullanılarak SearchClient
yapılır.
// Upload sample hotel documents to the Search Index
uploadDocuments(searchClient);
Bu, tüm komutları sıralı olarak çalıştıran bir konsol uygulaması olduğundan, dizin oluşturma ve sorgular arasında 2 saniyelik bekleme süresi ekleyin.
// 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)
{
}
2 saniyelik gecikme, sorgular yürütülmeden önce tüm belgelerin dizine alınabilmesi için zaman uyumsuz olan dizin oluşturmayı telafi eder. Gecikmeli kodlama genellikle yalnızca tanıtımlarda, testlerde ve örnek uygulamalarda gereklidir.
Dizin arama
İlk belge dizine alınır başlatılmaz sorgu sonuçlarını alabilirsiniz, ancak dizininizin gerçek testi tüm belgeler dizine alınana kadar beklemelidir.
Bu bölüm iki işlev parçası ekler: sorgu mantığı ve sonuçlar. Sorgular için Search yöntemini kullanın. Bu yöntem arama metnini (sorgu dizesi) ve diğer seçenekleri alır.
içinde App.java
, arama sonuçlarını konsola yazdıran bir WriteDocuments
yöntem oluşturun.
// 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();
}
Sorguları yürütmek ve sonuçları döndürmek için bir RunQueries
yöntem oluşturun. Sonuçlar nesnelerdir Hotel
. Bu örnek yöntem imzasını ve ilk sorguyu gösterir. Bu sorgu, belgeden Select
seçilen alanları kullanarak sonucu oluşturmanızı sağlayan parametreyi gösterir.
// 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));
}
İkinci sorguda terimi arayın, Derecelendirmenin 4'ten büyük olduğu belgeleri seçen bir filtre ekleyin ve ardından Azalan düzende Derecelendirmeye göre sıralayın. Filtre, bir dizindeki alanlar üzerinde isFilterable
değerlendirilen boole ifadesidir. Filtre sorguları değerleri içerir veya hariç tutar. Bu nedenle, filtre sorgusuyla ilişkilendirilmiş bir ilgi puanı yoktur.
// 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));
Üçüncü sorgu, bir tam metin arama işleminin kapsamını belirli alanlara göre ayarlamak için kullanılan öğesini gösterir 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));
Dördüncü sorgu, modelli bir gezinti yapısını yapılandırmak için kullanılabilen öğesini gösterir facets
.
// 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));
Beşinci sorguda belirli bir belgeyi döndürür.
// 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();
Son sorgu, dizinde tanımladığınız önericisi ile ilişkili iki olası eşleşmeye sourceFields
çözümleyen kısmi kullanıcı girişinin benzetimini yaparak otomatik tamamlama söz dizimini gösterir.
// Query 6
System.out.println("Query #6: Call Autocomplete on HotelName that starts with 's'...\n");
WriteAutocompleteResults(searchClient.autocomplete("s", "sg"));
Add RunQueries
to Main()
.
// 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");
Önceki sorgular sorguda terimleri eşleştirmenin birden çok yolunu gösterir: tam metin araması, filtreler ve otomatik tamamlama.
Tam metin araması ve filtreleri SearchClient.search yöntemi kullanılarak gerçekleştirilir. Arama sorgusu dizede searchText
geçirilebilirken SearchOptions sınıfının özelliğinde filter
bir filtre ifadesi geçirilebilir. Arama yapmadan filtrelemek için yönteminin searchText
parametresi için "*" geçirmesi search
gerekir. Filtreleme olmadan arama yapmak için özelliğini ayarsız bırakın filter
veya bir SearchOptions
örneği hiç geçirmeyin.
Programı çalıştırma
Uygulamayı yeniden derlemek ve programı tamamen çalıştırmak için F5 tuşuna basın.
Çıktı, sorgu bilgilerinin ve sonuçların eklenmesiyle gelen iletileri System.out.println
içerir.
Arama dizini oluşturmak, yüklemek ve sorgulamak için @azure/search-documents kitaplığını kullanarak bir Node.js uygulaması oluşturun.
Alternatif olarak, tamamlanmış bir projeyle başlamak için kaynak kodu indirebilir veya kendi projenizi oluşturmak için bu adımları izleyebilirsiniz.
Ortamınızı ayarlama
Bu hızlı başlangıcı oluşturmak için aşağıdaki araçları kullandık.
Proje oluşturma
Visual Studio Code’u başlatın.
Ctrl+Shift+P tuşlarını kullanarak Komut Paleti'ni açın ve tümleşik terminali açın.
Hızlı başlangıç adını vererek bir geliştirme dizini oluşturun:
mkdir quickstart
cd quickstart
Aşağıdaki komutu çalıştırarak npm ile boş bir proje başlatın. Projeyi tam olarak başlatmak için, MIT olarak ayarlamanız gereken Lisans dışında varsayılan değerleri kabul etmek için Enter tuşuna birden çok kez basın.
npm init
Azure AI Search için JavaScript/TypeScript SDK'sını yükleyin@azure/search-documents
.
npm install @azure/search-documents
Arama hizmeti adınız ve API anahtarınız gibi ortam değişkenlerini içeri aktarmak için kullanılan öğesini yükleyin dotenv
.
npm install dotenv
Hızlı başlangıç dizinine gidin, ardından package.json dosyanızın aşağıdaki json'a benzer olup olmadığını denetleyerek projeyi ve bağımlılıklarını yapılandırdığınızdan emin olun:
{
"name": "quickstart",
"version": "1.0.0",
"description": "Azure AI Search Quickstart",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"Azure",
"Search"
],
"author": "Your Name",
"license": "MIT",
"dependencies": {
"@azure/search-documents": "^11.3.0",
"dotenv": "^16.0.2"
}
}
Arama hizmeti parametrelerinizi tutmak için bir .env dosyası oluşturun:
SEARCH_API_KEY=<YOUR-SEARCH-ADMIN-API-KEY>
SEARCH_API_ENDPOINT=<YOUR-SEARCH-SERVICE-URL>
YOUR-SEARCH-SERVICE-URL
değerini arama hizmeti uç noktası URL'nizin adıyla değiştirin. değerini daha önce kaydettiğiniz yönetici anahtarıyla değiştirin <YOUR-SEARCH-ADMIN-API-KEY>
.
index.js dosyası oluşturma
Ardından kodumuzu barındıran ana dosya olan bir index.js dosyası oluşturacağız.
Bu dosyanın en üstünde kitaplığı içeri @azure/search-documents
aktarıyoruz:
const { SearchIndexClient, SearchClient, AzureKeyCredential, odata } = require("@azure/search-documents");
Ardından, paketin dotenv
.env dosyasındaki parametrelerde aşağıdaki gibi okunmasını zorunlu kmalıyız:
// Load the .env file if it exists
require("dotenv").config();
// Getting endpoint and apiKey from .env file
const endpoint = process.env.SEARCH_API_ENDPOINT || "";
const apiKey = process.env.SEARCH_API_KEY || "";
İçeri aktarmalarımız ve ortam değişkenlerimiz hazır olduğu için ana işlevi tanımlamaya hazırız.
SDK'daki işlevlerin çoğu zaman uyumsuz olduğundan ana işlevimizi async
yaparız. Ayrıca, karşılaşılan hataları yakalamak ve günlüğe kaydetmek için ana işlevin altına bir main().catch()
de ekleriz:
async function main() {
console.log(`Running Azure AI Search JavaScript quickstart...`);
if (!endpoint || !apiKey) {
console.log("Make sure to set valid values for endpoint and apiKey with proper authorization.");
return;
}
// remaining quickstart code will go here
}
main().catch((err) => {
console.error("The sample encountered an error:", err);
});
Bu durumda bir dizin oluşturmaya hazırız.
Dizin oluşturma
Dosya hotels_quickstart_index.json oluşturun. Bu dosya, Azure AI Search'in bir sonraki adımda yüklenecek belgelerle nasıl çalıştığını tanımlar. Her alan tarafından name
tanımlanır ve belirtilen type
değerine sahip olur. Her alan, Azure AI Search'ün alanda arama, filtreleme, sıralama ve model oluşturup oluşturmayacağını belirten bir dizi dizin özniteliğine de sahiptir. Alanların çoğu basit veri türleridir, ancak bazıları, AddressType
dizininizde zengin veri yapıları oluşturmanıza olanak sağlayan karmaşık türlerdir. Dizin Oluşturma (REST) bölümünde açıklanan desteklenen veri türleri ve dizin öznitelikleri hakkında daha fazla bilgi edinebilirsiniz.
Dosyayı hotels_quickstart_index.json veya indirmek için aşağıdaki içeriği ekleyin.
{
"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"
]
}
]
}
Dizin tanımımız yerinde olduğundan, ana işlevin dizin tanımına erişebilmesi için index.js en üstündeki hotels_quickstart_index.json içeri aktarmak istiyoruz.
const indexDefinition = require('./hotels_quickstart_index.json');
Ana işlevin içinde, Azure AI Search dizinlerini oluşturmak ve yönetmek için kullanılan bir SearchIndexClient
oluştururuz.
const indexClient = new SearchIndexClient(endpoint, new AzureKeyCredential(apiKey));
Ardından, zaten varsa dizini silmek istiyoruz. Bu işlem, test/tanıtım kodu için yaygın bir uygulamadır.
Bunu, dizini silmeye çalışan basit bir işlev tanımlayarak yaparız.
async function deleteIndexIfExists(indexClient, indexName) {
try {
await indexClient.deleteIndex(indexName);
console.log('Deleting index...');
} catch {
console.log('Index does not exist yet.');
}
}
İşlevi çalıştırmak için dizin tanımından dizin adını ayıklar ve indexName
ile birlikte indexClient
işlevini geçiririz deleteIndexIfExists()
.
const indexName = indexDefinition["name"];
console.log('Checking if index exists...');
await deleteIndexIfExists(indexClient, indexName);
Bundan sonra, yöntemiyle createIndex()
dizini oluşturmaya hazırız.
console.log('Creating index...');
let index = await indexClient.createIndex(indexDefinition);
console.log(`Index named ${index.name} has been created.`);
Örneği çalıştırma
Bu noktada, örneği çalıştırmaya hazırsınız. Aşağıdaki komutu çalıştırmak için bir terminal penceresi kullanın:
node index.js
Kaynak kodu indirdiyseniz ve gerekli paketleri henüz yüklemediyseniz önce komutunu çalıştırınnpm install
.
Program tarafından gerçekleştirilmekte olan eylemleri açıklayan bir dizi ileti görmeniz gerekir.
Azure portalında arama hizmetinize genel bakış'i açın. Dizinler sekmesini seçin. Aşağıdaki örneğe benzer bir şey görmeniz gerekir:
Sonraki adımda dizine veri ekleyeceksiniz.
Belge yükleme
Azure AI Search'te belgeler hem dizin oluşturmaya giriş hem de sorgulardan alınan çıkışlar olan veri yapılarıdır. Bu tür verileri dizine gönderebilirsiniz veya dizin oluşturucu kullanabilirsiniz. Bu durumda, belgeleri programlı olarak dizine göndereceğiz.
Belge girişleri veritabanındaki satırlar, Blob depolamadaki bloblar veya bu örnekte olduğu gibi diskteki JSON belgeleri olabilir. hotels.json indirebilir veya aşağıdaki içeriğe sahip kendi hotels.json dosyanızı oluşturabilirsiniz:
{
"value": [
{
"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.",
"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": "Old Century 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.",
"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": "Gastronomic 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 Palace 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.",
"Description_fr": "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.",
"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"
}
}
]
}
ile indexDefinition
yaptığımıza benzer şekilde, verilere ana işlevimizde erişebilmek için index.js en üstünde içeri aktarmamız hotels.json
gerekir.
const hotelData = require('./hotels.json');
Verileri arama dizinine dizine almak için şimdi bir SearchClient
oluşturmamız gerekir. SearchIndexClient
dizini oluşturmak ve yönetmek için kullanılırken, SearchClient
belgeleri karşıya yüklemek ve dizini sorgulamak için kullanılır.
oluşturmanın SearchClient
iki yolu vardır. İlk seçenek sıfırdan oluşturmaktır SearchClient
:
const searchClient = new SearchClient(endpoint, indexName, new AzureKeyCredential(apiKey));
Alternatif olarak, yöntemini SearchIndexClient
kullanarak getSearchClient()
öğesini oluşturabilirsinizSearchClient
:
const searchClient = indexClient.getSearchClient(indexName);
İstemci tanımlandığına göre, belgeleri arama dizinine yükleyin. Bu durumda, belgeleri karşıya yükleyen veya aynı anahtara sahip bir belge zaten varsa bunları mevcut bir belgeyle birleyen yöntemini kullanırız mergeOrUploadDocuments()
.
console.log('Uploading documents...');
let indexDocumentsResult = await searchClient.mergeOrUploadDocuments(hotelData['value']);
console.log(`Index operations succeeded: ${JSON.stringify(indexDocumentsResult.results[0].succeeded)}`);
ile programı yeniden node index.js
çalıştırın. 1. Adımda gördüklerinizden biraz farklı bir ileti kümesi görmeniz gerekir. Bu kez dizin mevcut ve uygulama yeni dizin oluşturmadan ve verileri bu dizine göndermeden önce bu dizini silmeyle ilgili bir ileti görmeniz gerekir.
Sonraki adımda sorguları çalıştırmadan önce, programın bir saniye beklemesini sağlamak için bir işlev tanımlayın. Bu, yalnızca dizin oluşturmanın tamamlanmasını ve belgelerin sorgularımız için dizinde kullanılabilir olmasını sağlamak amacıyla test/tanıtım amacıyla yapılır.
function sleep(ms) {
var d = new Date();
var d2 = null;
do {
d2 = new Date();
} while (d2 - d < ms);
}
Programın bir saniye beklemesini sağlamak için işlevi aşağıdaki gibi çağırın sleep
:
sleep(1000);
Dizin arama
Bir dizin oluşturulduğunda ve belgeler karşıya yüklendiğinde, dizine sorgu göndermeye hazırsınız demektir. Bu bölümde, kullanabileceğiniz farklı sorgu işlevlerini göstermek için arama dizinine beş farklı sorgu göndereceğiz.
Sorgular, main işlevinde çağırdığımız bir sendQueries()
işlevde aşağıdaki gibi yazılır:
await sendQueries(searchClient);
Sorgular yöntemi searchClient
kullanılarak search()
gönderilir. İlk parametre arama metnidir ve ikinci parametre arama seçeneklerini belirtir.
İlk sorgu, her şeyi aramaya eşdeğer olan öğesini arar *
ve dizindeki üç alanı seçer. Gereksiz verilerin geri çekilmesi sorgularınıza gecikme süresi kazandırabileceğinden, yalnızca select
ihtiyacınız olan alanları kullanmak en iyi yöntemdir.
searchOptions
Bu sorgunun değeri, bulunan eşleşen sonuç sayısını döndüren olarak da includeTotalCount
ayarlanmıştırtrue
.
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
}
Aşağıda özetlenen diğer sorgular da işleve sendQueries()
eklenmelidir. Okunabilirlik için burada ayrılmışlardır.
Sonraki sorguda, arama terimini "wifi"
belirtir ve ayrıca yalnızca durumun değerine eşit olduğu sonuçları döndürmek için 'FL'
bir filtre ekleriz. Sonuçlar ayrıca otel Rating
tarafından sipariş edilir.
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)}`);
}
Ardından, arama parametresi kullanılarak tek bir aranabilir alanla searchFields
sınırlıdır. Bu yaklaşım, yalnızca belirli alanlardaki eşleşmelerle ilgilendiğinizi biliyorsanız sorgunuzu daha verimli hale getirmek için harika bir seçenektir.
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();
Sorguya dahil etmek için sık kullanılan bir diğer seçenek de 'dir facets
. Modeller, kullanıcıların hangi değerlere filtre uygulayabileceklerini öğrenmesini kolaylaştırmak için kullanıcı arabiriminizde filtreler oluşturmanıza olanak tanır.
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)}`);
}
Son sorgu yöntemini getDocument()
searchClient
kullanır. Bu, bir belgeyi anahtarına göre verimli bir şekilde almanıza olanak tanır.
console.log('Query #5 - Lookup document:');
let documentResult = await searchClient.getDocument(key='3')
console.log(`HotelId: ${documentResult.HotelId}; HotelName: ${documentResult.HotelName}`)
Örneği çalıştırma
kullanarak node index.js
programı çalıştırın. Şimdi, önceki adımlara ek olarak sorgular gönderilir ve sonuçlar konsola yazılır.
Arama dizini oluşturmak, yüklemek ve sorgulamak için @azure/search-documents kitaplığını kullanarak bir Node.js uygulaması oluşturun.
Alternatif olarak, tamamlanmış bir projeyle başlamak için kaynak kodu indirebilir veya kendi projenizi oluşturmak için bu adımları izleyebilirsiniz.
Ortamınızı ayarlama
Bu hızlı başlangıcı oluşturmak için aşağıdaki araçları kullandık.
Proje oluşturma
Visual Studio Code’u başlatın.
Ctrl+Shift+P tuşlarını kullanarak Komut Paleti'ni açın ve tümleşik terminali açın.
Hızlı başlangıç adını vererek bir geliştirme dizini oluşturun:
mkdir quickstart
cd quickstart
Aşağıdaki komutu çalıştırarak npm ile boş bir proje başlatın. Projeyi tam olarak başlatmak için, MIT olarak ayarlamanız gereken Lisans dışında varsayılan değerleri kabul etmek için Enter tuşuna birden çok kez basın.
npm init
Azure AI Search için JavaScript/TypeScript SDK'sını yükleyin@azure/search-documents
.
npm install @azure/search-documents
Arama hizmeti adınız ve API anahtarınız gibi ortam değişkenlerini içeri aktarmak için kullanılan öğesini yükleyin dotenv
.
npm install dotenv
Hızlı başlangıç dizinine gidin, ardından package.json dosyanızın aşağıdaki json'a benzer olup olmadığını denetleyerek projeyi ve bağımlılıklarını yapılandırdığınızdan emin olun:
{
"name": "quickstart",
"version": "1.0.0",
"description": "Azure AI Search Quickstart",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"Azure",
"Search"
],
"author": "Your Name",
"license": "MIT",
"dependencies": {
"@azure/search-documents": "^12.1.0",
"dotenv": "^16.4.5"
}
}
Arama hizmeti parametrelerinizi tutmak için bir .env dosyası oluşturun:
SEARCH_API_KEY=<YOUR-SEARCH-ADMIN-API-KEY>
SEARCH_API_ENDPOINT=<YOUR-SEARCH-SERVICE-URL>
YOUR-SEARCH-SERVICE-URL
değerini arama hizmeti uç noktası URL'nizin adıyla değiştirin. değerini daha önce kaydettiğiniz yönetici anahtarıyla değiştirin <YOUR-SEARCH-ADMIN-API-KEY>
.
index.ts dosyası oluşturma
Ardından kodumuzu barındıran ana dosya olan bir index.ts dosyası oluşturacağız.
Bu dosyanın en üstünde kitaplığı içeri @azure/search-documents
aktarıyoruz:
import {
AzureKeyCredential,
ComplexField,
odata,
SearchClient,
SearchFieldArray,
SearchIndex,
SearchIndexClient,
SearchSuggester,
SimpleField
} from "@azure/search-documents";
Ardından, paketin dotenv
.env dosyasındaki parametrelerde aşağıdaki gibi okunmasını zorunlu kmalıyız:
// Load the .env file if it exists
import dotenv from 'dotenv';
dotenv.config();
// Getting endpoint and apiKey from .env file
const endpoint = process.env.SEARCH_API_ENDPOINT || "";
const apiKey = process.env.SEARCH_API_KEY || "";
İçeri aktarmalarımız ve ortam değişkenlerimiz hazır olduğu için ana işlevi tanımlamaya hazırız.
SDK'daki işlevlerin çoğu zaman uyumsuz olduğundan ana işlevimizi async
yaparız. Ayrıca, karşılaşılan hataları yakalamak ve günlüğe kaydetmek için ana işlevin altına bir main().catch()
de ekleriz:
async function main() {
console.log(`Running Azure AI Search JavaScript quickstart...`);
if (!endpoint || !apiKey) {
console.log("Make sure to set valid values for endpoint and apiKey with proper authorization.");
return;
}
// remaining quickstart code will go here
}
main().catch((err) => {
console.error("The sample encountered an error:", err);
});
Bu durumda bir dizin oluşturmaya hazırız.
Dizin oluşturma
Dosya hotels_quickstart_index.json oluşturun. Bu dosya, Azure AI Search'in bir sonraki adımda yüklenecek belgelerle nasıl çalıştığını tanımlar. Her alan tarafından name
tanımlanır ve belirtilen type
değerine sahip olur. Her alan, Azure AI Search'ün alanda arama, filtreleme, sıralama ve model oluşturup oluşturmayacağını belirten bir dizi dizin özniteliğine de sahiptir. Alanların çoğu basit veri türleridir, ancak bazıları, AddressType
dizininizde zengin veri yapıları oluşturmanıza olanak sağlayan karmaşık türlerdir. Dizin Oluşturma (REST) bölümünde açıklanan desteklenen veri türleri ve dizin öznitelikleri hakkında daha fazla bilgi edinebilirsiniz.
Dosyayı hotels_quickstart_index.json veya indirmek için aşağıdaki içeriği ekleyin.
{
"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"
]
}
]
}
Dizin tanımımız gerçekleştiğinde, ana işlevin dizin tanımına erişebilmesi için index.ts en üstündeki hotels_quickstart_index.json içeri aktarmak istiyoruz.
// Importing the index definition and sample data
import indexDefinition from './hotels_quickstart_index.json';
interface HotelIndexDefinition {
name: string;
fields: SimpleField[] | ComplexField[];
suggesters: SearchSuggester[];
};
const hotelIndexDefinition: HotelIndexDefinition = indexDefinition as HotelIndexDefinition;
Ana işlevin içinde, Azure AI Search dizinlerini oluşturmak ve yönetmek için kullanılan bir SearchIndexClient
oluştururuz.
const indexClient = new SearchIndexClient(endpoint, new AzureKeyCredential(apiKey));
Ardından, zaten varsa dizini silmek istiyoruz. Bu işlem, test/tanıtım kodu için yaygın bir uygulamadır.
Bunu, dizini silmeye çalışan basit bir işlev tanımlayarak yaparız.
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.');
}
}
İşlevi çalıştırmak için dizin tanımından dizin adını ayıklar ve indexName
ile birlikte indexClient
işlevini geçiririz deleteIndexIfExists()
.
// 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);
Bundan sonra, yöntemiyle createIndex()
dizini oluşturmaya hazırız.
console.log('Creating index...');
let index = await indexClient.createIndex(hotelIndexDefinition);
console.log(`Index named ${index.name} has been created.`);
Örneği çalıştırma
Bu noktada, örneği derlemeye ve çalıştırmaya hazırsınız. Aşağıdaki komutları çalıştırarak kaynağınızı ile tsc
oluşturmak ve ardından ile kaynağınızı node
çalıştırmak için bir terminal penceresi kullanın:
tsc
node index.ts
Kaynak kodu indirdiyseniz ve gerekli paketleri henüz yüklemediyseniz önce komutunu çalıştırınnpm install
.
Program tarafından gerçekleştirilmekte olan eylemleri açıklayan bir dizi ileti görmeniz gerekir.
Azure portalında arama hizmetinize genel bakış'i açın. Dizinler sekmesini seçin. Aşağıdaki örneğe benzer bir şey görmeniz gerekir:
Sonraki adımda dizine veri ekleyeceksiniz.
Belge yükleme
Azure AI Search'te belgeler hem dizin oluşturmaya giriş hem de sorgulardan alınan çıkışlar olan veri yapılarıdır. Bu tür verileri dizine gönderebilirsiniz veya dizin oluşturucu kullanabilirsiniz. Bu durumda, belgeleri programlı olarak dizine göndereceğiz.
Belge girişleri veritabanındaki satırlar, Blob depolamadaki bloblar veya bu örnekte olduğu gibi diskteki JSON belgeleri olabilir. hotels.json indirebilir veya aşağıdaki içeriğe sahip kendi hotels.json dosyanızı oluşturabilirsiniz:
{
"value": [
{
"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.",
"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": "Old Century 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.",
"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": "Gastronomic 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 Palace 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.",
"Description_fr": "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.",
"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"
}
}
]
}
indexDefinition ile yaptığımıza benzer şekilde, verilere ana işlevimizden erişebilmek için index.ts en üstünde içeri aktarmamız hotels.json
gerekir.
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"];
Verileri arama dizinine dizine almak için şimdi bir SearchClient
oluşturmamız gerekir. SearchIndexClient
dizini oluşturmak ve yönetmek için kullanılırken, SearchClient
belgeleri karşıya yüklemek ve dizini sorgulamak için kullanılır.
oluşturmanın SearchClient
iki yolu vardır. İlk seçenek sıfırdan oluşturmaktır SearchClient
:
const searchClient = new SearchClient<Hotel>(endpoint, indexName, new AzureKeyCredential(apiKey));
Alternatif olarak, yöntemini SearchIndexClient
kullanarak getSearchClient()
öğesini oluşturabilirsinizSearchClient
:
const searchClient = indexClient.getSearchClient<Hotel>(indexName);
İstemci tanımlandığına göre, belgeleri arama dizinine yükleyin. Bu durumda, belgeleri karşıya yükleyen veya aynı anahtara sahip bir belge zaten varsa bunları mevcut bir belgeyle birleyen yöntemini kullanırız mergeOrUploadDocuments()
. Ardından, en azından ilk belge mevcut olduğundan işlemin başarılı olup olmadığını denetleyin.
console.log("Uploading documents...");
const indexDocumentsResult = await searchClient.mergeOrUploadDocuments(hotels);
console.log(`Index operations succeeded: ${JSON.stringify(indexDocumentsResult.results[0].succeeded)}`);
ile programı yeniden tsc && node index.ts
çalıştırın. 1. Adımda gördüklerinizden biraz farklı bir ileti kümesi görmeniz gerekir. Bu kez dizin mevcut ve uygulama yeni dizin oluşturmadan ve verileri bu dizine göndermeden önce bu dizini silmeyle ilgili bir ileti görmeniz gerekir.
Sonraki adımda sorguları çalıştırmadan önce, programın bir saniye beklemesini sağlamak için bir işlev tanımlayın. Bu, yalnızca dizin oluşturmanın tamamlanmasını ve belgelerin sorgularımız için dizinde kullanılabilir olmasını sağlamak amacıyla test/tanıtım amacıyla yapılır.
function sleep(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
Programın bir saniye beklemesini sağlamak için işlevini çağırın sleep
:
sleep(1000);
Dizin arama
Bir dizin oluşturulduğunda ve belgeler karşıya yüklendiğinde, dizine sorgu göndermeye hazırsınız demektir. Bu bölümde, kullanabileceğiniz farklı sorgu işlevlerini göstermek için arama dizinine beş farklı sorgu göndereceğiz.
Sorgular, main işlevinde çağırdığımız bir sendQueries()
işlevde aşağıdaki gibi yazılır:
await sendQueries(searchClient);
Sorgular yöntemi searchClient
kullanılarak search()
gönderilir. İlk parametre arama metnidir ve ikinci parametre arama seçeneklerini belirtir.
İlk sorgu, her şeyi aramaya eşdeğer olan öğesini arar *
ve dizindeki üç alanı seçer. Gereksiz verilerin geri çekilmesi sorgularınıza gecikme süresi kazandırabileceğinden, yalnızca select
ihtiyacınız olan alanları kullanmak en iyi yöntemdir.
searchOptions
Bu sorgu için de olarak ayarlanmıştır includeTotalCount
true
ve bu da bulunan eşleşen sonuç sayısını döndürür.
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
}
Aşağıda özetlenen diğer sorgular da işleve sendQueries()
eklenmelidir. Okunabilirlik için burada ayrılmışlardır.
Sonraki sorguda, arama terimini "wifi"
belirtir ve ayrıca yalnızca durumun değerine eşit olduğu sonuçları döndürmek için 'FL'
bir filtre ekleriz. Sonuçlar ayrıca otel Rating
tarafından sipariş edilir.
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)}`);
}
Ardından, arama parametresi kullanılarak tek bir aranabilir alanla searchFields
sınırlıdır. Bu yaklaşım, yalnızca belirli alanlardaki eşleşmelerle ilgilendiğinizi biliyorsanız sorgunuzu daha verimli hale getirmek için harika bir seçenektir.
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)}`);
}
Sorguya dahil etmek için sık kullanılan bir diğer seçenek de 'dir facets
. Modeller, kullanıcı arabiriminizdeki sonuçlardan kendi kendine detaya gitme olanağı sağlar. Model sonuçları, sonuç bölmesinde onay kutularına dönüştürülebilir.
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)}`);
}
Son sorgu yöntemini getDocument()
searchClient
kullanır. Bu, bir belgeyi anahtarına göre verimli bir şekilde almanıza olanak tanır.
console.log('Query #5 - Lookup document:');
let documentResult = await searchClient.getDocument('3')
console.log(`HotelId: ${documentResult.HotelId}; HotelName: ${documentResult.HotelName}`)
Örneği yeniden çalıştırma
ile tsc && node index.ts
programı derleyin ve çalıştırın. Şimdi, önceki adımlara ek olarak sorgular gönderilir ve sonuçlar konsola yazılır.
Kendi aboneliğinizde çalışırken, projenin sonunda oluşturduğunuz kaynaklara hala ihtiyacınız olup olmadığını belirlemek iyi bir fikirdir. Çalışır durumda bırakılan kaynaklar maliyetlerin artmasına neden olabilir. Kaynakları teker teker silebilir veya tüm kaynak grubunu silerek kaynak kümesinin tamamını kaldırabilirsiniz.
Ücretsiz bir hizmet kullanıyorsanız üç dizin, dizin oluşturucu ve veri kaynağıyla sınırlı olduğunuzu unutmayın. Sınırın altında kalmak için portaldaki tek tek öğeleri silebilirsiniz.
Bu hızlı başlangıçta, dizin oluşturmak, belgelerle yüklemek ve sorgu çalıştırmak için bir dizi görev üzerinde çalıştınız. Farklı aşamalarda, okunabilirlik ve kavrama kodunu basitleştirmek için kısayolları kullandık. Temel kavramları bildiğinize göre artık bir web uygulamasında Azure AI Arama API'lerini çağıran bir öğreticiyi deneyin.