C# .NET uygulamasında Microsoft.Azure.Search kullanma
Bu makalede, .NET için Azure SDK'da C# ve eski istemci kitaplığı olan Microsoft.Azure.Search (sürüm 10) kullanılarak arama nesnelerinin nasıl oluşturulacağı ve yönetileceğini açıklanmaktadır.
Sürüm 10, Microsoft.Azure.Search paketinin son sürümüdür. Bundan sonra yeni özellikler Azure SDK ekibinden Azure.Search.Documents'ta kullanıma sunulacaktır.
Not
Mevcut veya uçak içi geliştirme projeleriniz varsa, 10 sürümünü kullanmaya devam edebilirsiniz. Yeni projelerde veya yeni özellikleri kullanmak için yeni kitaplığa geçmeniz gerekir.
Sürüm 10 hakkında
SDK, dizinlerinizi, veri kaynaklarınızı, dizin oluşturucularınızı ve eş anlamlı eşlemelerinizi yönetmenizi, ayrıca HTTP ve JSON ayrıntılarıyla ilgilenmenize gerek kalmadan belgeleri karşıya yükleyip yönetmenizi ve sorguları yürütmenizi sağlayan birkaç istemci kitaplığından oluşur. Bu istemci kitaplıklarının tümü NuGet paketleri olarak dağıtılır.
Ana NuGet paketi, Microsoft.Azure.Search
diğer tüm paketleri bağımlılık olarak içeren bir meta pakettir. Yeni başlıyorsanız veya uygulamanızın tüm Azure Bilişsel Arama özelliklerine ihtiyacı olacağını biliyorsanız bu paketi kullanın.
SDK'daki diğer NuGet paketleri şunlardır:
Microsoft.Azure.Search.Data
: Azure Bilişsel Arama kullanarak bir .NET uygulaması geliştiriyorsanız ve yalnızca dizinlerinizdeki belgeleri sorgulamanız veya güncelleştirmeniz gerekiyorsa bu paketi kullanın. Dizinleri, eş anlamlı eşlemeleri veya diğer hizmet düzeyi kaynaklarını da oluşturmanız veya güncelleştirmeniz gerekiyorsa, bunun yerine paketini kullanınMicrosoft.Azure.Search
.Microsoft.Azure.Search.Service
: .NET'te Azure Bilişsel Arama dizinleri, eş anlamlı eşlemeleri, dizin oluşturucuları, veri kaynaklarını veya diğer hizmet düzeyi kaynaklarını yönetmek için otomasyon geliştiriyorsanız bu paketi kullanın. Yalnızca dizinlerinizdeki belgeleri sorgulamanız veya güncelleştirmeniz gerekiyorsa, bunun yerine paketini kullanınMicrosoft.Azure.Search.Data
. Azure Bilişsel Arama tüm işlevlerine ihtiyacınız varsa, bunun yerine paketini kullanınMicrosoft.Azure.Search
.Microsoft.Azure.Search.Common
: Azure Bilişsel Arama .NET kitaplıkları için gereken yaygın türler. Bu paketi doğrudan uygulamanızda kullanmanız gerekmez. Yalnızca bağımlılık olarak kullanılması amaçlanır.
Çeşitli istemci kitaplıkları, , ve gibi Index
sınıfların Document
yanı sıra ve SearchIndexClient
sınıflarında SearchServiceClient
ve Documents.Search
gibi Indexes.Create
işlemleri Field
tanımlar. Bu sınıflar aşağıdaki ad alanlarında düzenlenmiştir:
SDK'nın gelecekteki bir güncelleştirmesi için geri bildirim sağlamak isterseniz geri bildirim sayfamıza bakın veya GitHub üzerinde bir sorun oluşturun ve sorun başlığında "Azure Bilişsel Arama" ifadesini belirtin.
.NET SDK, Azure Bilişsel Arama REST API sürümünü2019-05-06
hedefler. Bu sürüm, Azure Bloblarını dizine eklerken karmaşık türler, yapay zeka zenginleştirmesi, otomatik tamamlama ve JsonLines ayrıştırma modu desteği içerir.
Bu SDK, Arama hizmetlerini oluşturma ve ölçeklendirme ve API anahtarlarını yönetme gibi Yönetim İşlemlerini desteklemez. Arama kaynaklarınızı bir .NET uygulamasından yönetmeniz gerekiyorsa Azure Bilişsel Arama .NET Yönetim SDK'sını kullanabilirsiniz.
v10'a yükseltme
Azure Bilişsel Arama .NET SDK'sının daha eski bir sürümünü kullanıyorsanız ve genel olarak kullanılabilen en son sürüme yükseltmek istiyorsanız, bu makalede bunun nasıl yapıldığını açıklanmaktadır.
SDK gereksinimleri
- Visual Studio 2017 veya üzeri.
- Kendi Azure Bilişsel Arama hizmetiniz. SDK'yı kullanmak için hizmetinizin adına ve bir veya daha fazla API anahtarına ihtiyacınız olacaktır. Portalda bir hizmet oluşturmak , bu adımlarda size yardımcı olur.
- Visual Studio'da "NuGet Paketlerini Yönet" seçeneğini kullanarak Azure Bilişsel Arama .NET SDK NuGet paketini indirin. NuGet.org'da paket adını
Microsoft.Azure.Search
(veya işlevselliğin yalnızca bir alt kümesine ihtiyacınız varsa yukarıdaki diğer paket adlarından birini) aramanız yeterlidir.
Azure Bilişsel Arama .NET SDK, .NET Framework 4.5.2 ve üzerini hedefleyen uygulamaların yanı sıra .NET Core 2.0 ve üzerini destekler.
Temel senaryolar
Arama uygulamanızda yapmanız gereken birkaç şey vardır. Bu öğreticide şu temel senaryoları ele alacağız:
- Dizin oluşturma
- Dizini belgelerle doldurma
- Tam metin arama ve filtreleri kullanarak belge arama
Aşağıdaki örnek kodda bu senaryoların her biri gösterilmektedir. Kod parçacıklarını kendi uygulamanızda kullanmaktan çekinmeyin.
Genel Bakış
Araştıracağımız örnek uygulama "hotels" adlı yeni bir dizin oluşturur, bunu birkaç belgeyle doldurur ve ardından bazı arama sorguları yürütür. Genel akışı gösteren ana program aşağıdadır:
// This sample shows how to delete, create, upload documents and query an index
static void Main(string[] args)
{
IConfigurationBuilder builder = new ConfigurationBuilder().AddJsonFile("appsettings.json");
IConfigurationRoot configuration = builder.Build();
SearchServiceClient serviceClient = CreateSearchServiceClient(configuration);
string indexName = configuration["SearchIndexName"];
Console.WriteLine("{0}", "Deleting index...\n");
DeleteIndexIfExists(indexName, serviceClient);
Console.WriteLine("{0}", "Creating index...\n");
CreateIndex(indexName, serviceClient);
ISearchIndexClient indexClient = serviceClient.Indexes.GetClient(indexName);
Console.WriteLine("{0}", "Uploading documents...\n");
UploadDocuments(indexClient);
ISearchIndexClient indexClientForQueries = CreateSearchIndexClient(configuration);
RunQueries(indexClientForQueries);
Console.WriteLine("{0}", "Complete. Press any key to end application...\n");
Console.ReadKey();
}
Not
Bu kılavuzda kullanılan örnek uygulamanın tam kaynak kodunu GitHub üzerinde bulabilirsiniz.
Bu adımı adım adım inceleyeceğiz. İlk olarak yeni SearchServiceClient
bir oluşturmalıyız. Bu nesne dizinleri yönetmenize olanak tanır. Bir hizmet oluşturmak için Azure Bilişsel Arama hizmet adınızın yanı sıra bir yönetici API anahtarı sağlamanız gerekir. Bu bilgileri appsettings.json
örnek uygulamanın dosyasına girebilirsiniz.
private static SearchServiceClient CreateSearchServiceClient(IConfigurationRoot configuration)
{
string searchServiceName = configuration["SearchServiceName"];
string adminApiKey = configuration["SearchServiceAdminApiKey"];
SearchServiceClient serviceClient = new SearchServiceClient(searchServiceName, new SearchCredentials(adminApiKey));
return serviceClient;
}
Not
Yanlış bir anahtar (örneğin, bir yönetici anahtarının gerekli olduğu bir sorgu anahtarı) SearchServiceClient
sağlarsanız, gibi bir işlem yöntemini Indexes.Create
ilk kez çağırdığınızda "Yasak" hata iletisini içeren bir oluştururCloudException
. Bu durumda API anahtarımızı bir kez daha denetleyin.
Sonraki birkaç satır, "hotels" adlı bir dizin oluşturmak için yöntemleri çağırır ve önceden mevcutsa önce bu dizini siler. Bu yöntemleri biraz daha sonra inceleyeceğiz.
Console.WriteLine("{0}", "Deleting index...\n");
DeleteIndexIfExists(indexName, serviceClient);
Console.WriteLine("{0}", "Creating index...\n");
CreateIndex(indexName, serviceClient);
Ardından dizinin doldurulması gerekir. Dizini doldurmak için bir SearchIndexClient
gerekir. Birini elde etmenin iki yolu vardır: bunu oluşturmak veya üzerinde SearchServiceClient
çağırarakIndexes.GetClient
. İkincisini kolaylık sağlamak için kullanırız.
ISearchIndexClient indexClient = serviceClient.Indexes.GetClient(indexName);
Not
Tipik bir arama uygulamasında dizin yönetimi ve popülasyon, arama sorgularından ayrı bir bileşen tarafından işlenebilir. Indexes.GetClient
bir dizini doldurmaya uygundur, çünkü ek SearchCredentials
sağlama konusunda sorun yaşamanızı sağlar. Yeni SearchIndexClient
için SearchServiceClient
oluşturmak üzere kullandığınız yönetici anahtarını geçirerek bunu yapar. Ancak, uygulamanızın sorguları yürüten bölümünde, doğrudan oluşturmak SearchIndexClient
daha iyidir; böylece bir sorgu anahtarı geçirebilirsiniz ve bu da bir yönetici anahtarı yerine yalnızca verileri okumanıza olanak tanır. Bu, en az ayrıcalık ilkesiyle tutarlıdır ve uygulamanızı daha güvenli hale getirmenize yardımcı olur. Yönetici anahtarları ve sorgu anahtarları hakkında daha fazla bilgi için buraya bakın.
Artık bir 'a sahip olduğumuza SearchIndexClient
göre dizini doldurabiliriz. Dizin popülasyonu, daha sonra izlenecek başka bir yöntemle gerçekleştirilir.
Console.WriteLine("{0}", "Uploading documents...\n");
UploadDocuments(indexClient);
Son olarak, birkaç arama sorgusu yürütür ve sonuçları görüntüleriz. Bu kez farklı SearchIndexClient
bir kullanırız:
ISearchIndexClient indexClientForQueries = CreateSearchIndexClient(indexName, configuration);
RunQueries(indexClientForQueries);
Yöntemi daha sonra daha yakından inceleyeceğiz RunQueries
. Yeni SearchIndexClient
oluşturma kodu aşağıdadır:
private static SearchIndexClient CreateSearchIndexClient(string indexName, IConfigurationRoot configuration)
{
string searchServiceName = configuration["SearchServiceName"];
string queryApiKey = configuration["SearchServiceQueryApiKey"];
SearchIndexClient indexClient = new SearchIndexClient(searchServiceName, indexName, new SearchCredentials(queryApiKey));
return indexClient;
}
Dizine yazma erişimine ihtiyacımız olmadığından bu kez bir sorgu anahtarı kullanıyoruz. Bu bilgileri appsettings.json
örnek uygulamanın dosyasına girebilirsiniz.
Bu uygulamayı geçerli bir hizmet adı ve API anahtarlarıyla çalıştırırsanız çıkış şu örneğe benzer olmalıdır: (Bazı konsol çıktısı "..." ile değiştirildi çizim amacıyla.)
Deleting index...
Creating index...
Uploading documents...
Waiting for documents to be indexed...
Search the entire index for the term 'motel' and return only the HotelName field:
Name: Secret Point Motel
Name: Twin Dome Motel
Apply a filter to the index to find hotels with a room cheaper than $100 per night, and return the hotelId and description:
HotelId: 1
Description: The hotel is ideally located on the main commercial artery of the city in the heart of New York. A few minutes away is Times Square and the historic centre of the city, as well as other places of interest that make New York one of America's most attractive and cosmopolitan cities.
HotelId: 2
Description: The hotel is situated in a nineteenth century plaza, which has been expanded and renovated to the highest architectural standards to create a modern, functional and first-class hotel in which art and unique historical elements coexist with the most modern comforts.
Search the entire index, order by a specific field (lastRenovationDate) in descending order, take the top two results, and show only hotelName and lastRenovationDate:
Name: Triple Landscape Hotel
Last renovated on: 9/20/2015 12:00:00 AM +00:00
Name: Twin Dome Motel
Last renovated on: 2/18/1979 12:00:00 AM +00:00
Search the hotel names for the term 'hotel':
HotelId: 3
Name: Triple Landscape Hotel
...
Complete. Press any key to end application...
Uygulamanın tam kaynak kodu bu makalenin sonunda sağlanır.
Ardından tarafından çağrılan Main
yöntemlerin her birine daha yakından bakacağız.
Dizin oluşturma
oluşturduktan SearchServiceClient
sonra , Main
zaten varsa "hotels" dizinini siler. Bu silme işlemi aşağıdaki yöntemle gerçekleştirilir:
private static void DeleteIndexIfExists(string indexName, SearchServiceClient serviceClient)
{
if (serviceClient.Indexes.Exists(indexName))
{
serviceClient.Indexes.Delete(indexName);
}
}
Bu yöntem, dizinin var olup olmadığını denetlemek ve varsa silmek için verilen SearchServiceClient
yöntemini kullanır.
Not
Bu makaledeki örnek kod, kolaylık sağlamak için Azure Bilişsel Arama .NET SDK'sının zaman uyumlu yöntemlerini kullanır. Kendi uygulamalarınızda zaman uyumsuz yöntemler kullanarak bunları ölçeklenebilir ve esnek tutmanızı öneririz. Örneğin, yukarıdaki yöntemde ve yerine Exists
ve DeleteAsync
Delete
kullanabilirsinizExistsAsync
.
Ardından, Main
şu yöntemi çağırarak yeni bir "hotels" dizini oluşturur:
private static void CreateIndex(string indexName, SearchServiceClient serviceClient)
{
var definition = new Index()
{
Name = indexName,
Fields = FieldBuilder.BuildForType<Hotel>()
};
serviceClient.Indexes.Create(definition);
}
Bu yöntem, yeni Index
dizinin şemasını Field
tanımlayan nesnelerin listesiyle yeni bir nesne oluşturur. Her alanın bir adı, veri türü ve arama davranışını tanımlayan birkaç özniteliği vardır. sınıfı, FieldBuilder
verilen Hotel
model sınıfının ortak özelliklerini ve özniteliklerini inceleyerek dizin için nesnelerin listesini Field
oluşturmak için yansıma kullanır. Daha sonra sınıfa Hotel
daha yakından bakacağız.
Not
Gerekirse kullanmak FieldBuilder
yerine her zaman doğrudan nesne listesi Field
oluşturabilirsiniz. Örneğin, bir model sınıfı kullanmak istemeyebilir veya öznitelik ekleyerek değiştirmek istemediğiniz mevcut bir model sınıfını kullanmanız gerekebilir.
Alanlara ek olarak, Dizine puanlama profilleri, önerenler veya CORS seçenekleri de ekleyebilirsiniz (bu parametreler kısa süre için örnekten atlanır). Index nesnesi ve bileşenleri hakkında daha fazla bilgiyi SDK başvurusunda ve Azure Bilişsel Arama REST API başvurusunda bulabilirsiniz.
Dizini doldurma
içindeki Main
bir sonraki adım, yeni oluşturulan dizini doldurur. Bu dizin popülasyonu şu yöntemde yapılır: (Bazı kodlar "..." ile değiştirildi çizim amacıyla. Tam veri popülasyonu kodu için tam örnek çözüme bakın.)
private static void UploadDocuments(ISearchIndexClient indexClient)
{
var hotels = new Hotel[]
{
new Hotel()
{
HotelId = "1",
HotelName = "Secret Point Motel",
...
Address = new Address()
{
StreetAddress = "677 5th Ave",
...
},
Rooms = new Room[]
{
new Room()
{
Description = "Budget Room, 1 Queen Bed (Cityside)",
...
},
new Room()
{
Description = "Budget Room, 1 King Bed (Mountain View)",
...
},
new Room()
{
Description = "Deluxe Room, 2 Double Beds (City View)",
...
}
}
},
new Hotel()
{
HotelId = "2",
HotelName = "Twin Dome Motel",
...
{
StreetAddress = "140 University Town Center Dr",
...
},
Rooms = new Room[]
{
new Room()
{
Description = "Suite, 2 Double Beds (Mountain View)",
...
},
new Room()
{
Description = "Standard Room, 1 Queen Bed (City View)",
...
},
new Room()
{
Description = "Budget Room, 1 King Bed (Waterfront View)",
...
}
}
},
new Hotel()
{
HotelId = "3",
HotelName = "Triple Landscape Hotel",
...
Address = new Address()
{
StreetAddress = "3393 Peachtree Rd",
...
},
Rooms = new Room[]
{
new Room()
{
Description = "Standard Room, 2 Queen Beds (Amenities)",
...
},
new Room ()
{
Description = "Standard Room, 2 Double Beds (Waterfront View)",
...
},
new Room()
{
Description = "Deluxe Room, 2 Double Beds (Cityside)",
...
}
}
}
};
var batch = IndexBatch.Upload(hotels);
try
{
indexClient.Documents.Index(batch);
}
catch (IndexBatchException e)
{
// Sometimes when your Search service is under load, indexing will fail for some of the documents in
// the batch. Depending on your application, you can take compensating actions like delaying and
// retrying. For this simple demo, we just log the failed document keys and continue.
Console.WriteLine(
"Failed to index some of the documents: {0}",
String.Join(", ", e.IndexingResults.Where(r => !r.Succeeded).Select(r => r.Key)));
}
Console.WriteLine("Waiting for documents to be indexed...\n");
Thread.Sleep(2000);
}
Bu yöntemin dört bölümü vardır. İlki, dizine yüklenecek giriş verilerimiz olarak görev yapacak 3 nesneden oluşan 3 Room
nesneden oluşan Hotel
bir dizi oluşturur. Bu veriler basitlik için sabit kodlanmıştır. Kendi uygulamanızda verileriniz büyük olasılıkla SQL veritabanı gibi bir dış veri kaynağından gelir.
İkinci bölüm, belgeleri içeren bir IndexBatch
oluşturur. Toplu işleme uygulamak istediğiniz işlemi, bu durumda çağrısı IndexBatch.Upload
yaparak oluştururken belirtirsiniz. Toplu işlem daha sonra yöntemiyle Azure Bilişsel Arama dizinine Documents.Index
yüklenir.
Not
Bu örnekte yalnızca belgeleri karşıya yüklüyoruz. Değişiklikleri var olan belgelerle birleştirmek veya silmek istiyorsanız, bunun yerine , veya IndexBatch.MergeOrUpload
IndexBatch.Delete
çağırarak IndexBatch.Merge
toplu iş oluşturabilirsiniz. Ayrıca, her biri Azure Bilişsel Arama belge üzerinde belirli bir işlemi gerçekleştirmesini söyleyen bir nesne koleksiyonu IndexAction
alan öğesini çağırarak IndexBatch.New
farklı işlemleri tek bir toplu işlemde karıştırabilirsiniz. , ve gibi IndexAction.Merge
IndexAction.Upload
ilgili yöntemi çağırarak her IndexAction
bir işlemi kendi işlemiyle oluşturabilirsiniz.
Bu yöntemin üçüncü bölümü, dizin oluşturma için önemli bir hata durumunu işleyen bir catch bloğudur. Azure Bilişsel Arama hizmetiniz toplu işlemdeki bazı belgelerin dizinini oluşturamazsa tarafından bir IndexBatchException
oluşturulurDocuments.Index
. Hizmetiniz ağır yük altındayken belgeleri dizine eklerken bu özel durum oluşabilir. Bu durumu açık bir şekilde kodunuzda işlemenizi kesinlikle öneririz. Başarısız olan belgelere dizin oluşturmayı geciktirip sonra yeniden deneyebilir veya günlük tutup örneğin devam ettiği şekilde devam edebilir veya uygulamanızın veri tutarlılığı gereksinimlerine bağlı olarak başka bir şey yapabilirsiniz.
Not
yöntemini kullanarak FindFailedActionsToRetry
yalnızca önceki çağrısında Index
başarısız olan eylemleri içeren yeni bir toplu iş oluşturabilirsiniz. StackOverflow'da düzgün bir şekilde nasıl kullanılacağına ilişkin bir tartışma vardır.
Son olarak, UploadDocuments
yöntem iki saniye boyunca geciktirildi. Dizin oluşturma, Azure Bilişsel Arama hizmetinizde zaman uyumsuz olarak gerçekleşir, bu nedenle örnek uygulamanın belgelerin arama için kullanılabilir olduğundan emin olmak için kısa bir süre beklemesi gerekir. Bu gibi gecikmeler genellikle yalnızca gösterilerde, testlerde ve örnek uygulamalarda gereklidir.
.NET SDK belgeleri nasıl işler?
Azure Bilişsel Arama .NET SDK'sının dizin gibi kullanıcı tanımlı bir sınıfın Hotel
örneklerini nasıl karşıya yükleyebildiğini merak ediyor olabilirsiniz. Bu soruyu yanıtlamaya yardımcı olmak için sınıfına Hotel
bakalım:
using System;
using Microsoft.Azure.Search;
using Microsoft.Azure.Search.Models;
using Microsoft.Spatial;
using Newtonsoft.Json;
public partial class Hotel
{
[System.ComponentModel.DataAnnotations.Key]
[IsFilterable]
public string HotelId { get; set; }
[IsSearchable, IsSortable]
public string HotelName { get; set; }
[IsSearchable]
[Analyzer(AnalyzerName.AsString.EnLucene)]
public string Description { get; set; }
[IsSearchable]
[Analyzer(AnalyzerName.AsString.FrLucene)]
[JsonProperty("Description_fr")]
public string DescriptionFr { get; set; }
[IsSearchable, IsFilterable, IsSortable, IsFacetable]
public string Category { get; set; }
[IsSearchable, IsFilterable, IsFacetable]
public string[] Tags { get; set; }
[IsFilterable, IsSortable, IsFacetable]
public bool? ParkingIncluded { get; set; }
// SmokingAllowed reflects whether any room in the hotel allows smoking.
// The JsonIgnore attribute indicates that a field should not be created
// in the index for this property and it will only be used by code in the client.
[JsonIgnore]
public bool? SmokingAllowed => (Rooms != null) ? Array.Exists(Rooms, element => element.SmokingAllowed == true) : (bool?)null;
[IsFilterable, IsSortable, IsFacetable]
public DateTimeOffset? LastRenovationDate { get; set; }
[IsFilterable, IsSortable, IsFacetable]
public double? Rating { get; set; }
public Address Address { get; set; }
[IsFilterable, IsSortable]
public GeographyPoint Location { get; set; }
public Room[] Rooms { get; set; }
}
Dikkat edilecek ilk şey, sınıftaki her ortak özelliğin adının dizin tanımında Hotel
aynı ada sahip bir alanla eşlenecek olmasıdır. Her alanın küçük harfle ("büyük harf") başlamasını istiyorsanız, SDK'ya özellik adlarını sınıftaki özniteliğiyle otomatik olarak deve-büyük/küçük harfle eşlemesini [SerializePropertyNamesAsCamelCase]
söyleyebilirsiniz. Bu senaryo, hedef şemanın .NET'teki "Pascal case" adlandırma yönergelerini ihlal etmek zorunda kalmadan uygulama geliştiricisinin denetimi dışında olduğu veri bağlama gerçekleştiren .NET uygulamalarında yaygındır.
Not
Azure Bilişsel Arama .NET SDK'sı, özel model nesnelerinizi JSON'a ve JSON'dan seri hale getirmek ve seri durumdan kaldırmak için NewtonSoft JSON.NET kitaplığını kullanır. Gerekirse bu seri hale getirmeyi özelleştirebilirsiniz. Daha fazla bilgi için bkz. JSON.NET ile Özel Serileştirme.
Dikkat edilmesi gereken ikinci şey, her özelliğin , IsSearchable
, Key
ve Analyzer
gibi IsFilterable
özniteliklerle donatılmasıdır. Bu öznitelikler doğrudan bir Azure Bilişsel Arama dizinindeki ilgili alan öznitelikleriyle eşler. sınıfı, FieldBuilder
dizin için alan tanımları oluşturmak için bu özellikleri kullanır.
Sınıfın Hotel
üçüncü önemli özelliği, ortak özelliklerin veri türleridir. Bu özelliklerin .NET türleri, dizin tanımında eşdeğer alan türleriyle eşlenir. Örneğin, Category
dize özelliği Edm.String
türündeki category
alanına eşlenir. , , Edm.Boolean
DateTimeOffset?
ve Edm.DateTimeOffset
benzeri arasında bool?
benzer tür eşlemeleri vardır. Tür eşlemesi için belirli kurallar Azure Bilişsel Arama .NET SDK başvurusundaki yöntemiyle Documents.Get
belgelenir. Sınıfı FieldBuilder
bu eşlemeyi sizin için halleder, ancak serileştirme sorunlarını gidermeniz gerektiğinde anlamanız yararlı olabilir.
Bu özelliği fark SmokingAllowed
ettiniz mi?
[JsonIgnore]
public bool? SmokingAllowed => (Rooms != null) ? Array.Exists(Rooms, element => element.SmokingAllowed == true) : (bool?)null;
JsonIgnore
Bu özellik üzerindeki özniteliği, dizinine alan olarak seri hale getirmemelerini söylerFieldBuilder
. Bu, uygulamanızda yardımcı olarak kullanabileceğiniz istemci tarafı hesaplanmış özellikleri oluşturmak için harika bir yoldur. Bu durumda, SmokingAllowed
özelliği koleksiyondaki herhangi bir Room
sigara içme Rooms
izin verilip verilmeyeceğini yansıtır. Hepsi yanlış ise, otelin tamamının sigara içilmediğine işaret eder.
ve Rooms
gibi Address
bazı özellikler .NET sınıflarının örnekleridir. Bu özellikler daha karmaşık veri yapılarını temsil eder ve sonuç olarak dizinde karmaşık veri türüne sahip alanlar gerektirir.
Address
özelliği, sınıfında aşağıda tanımlanan birden çok değer kümesini temsil ederAddress
:
using System;
using Microsoft.Azure.Search;
using Microsoft.Azure.Search.Models;
using Newtonsoft.Json;
namespace AzureSearch.SDKHowTo
{
public partial class Address
{
[IsSearchable]
public string StreetAddress { get; set; }
[IsSearchable, IsFilterable, IsSortable, IsFacetable]
public string City { get; set; }
[IsSearchable, IsFilterable, IsSortable, IsFacetable]
public string StateProvince { get; set; }
[IsSearchable, IsFilterable, IsSortable, IsFacetable]
public string PostalCode { get; set; }
[IsSearchable, IsFilterable, IsSortable, IsFacetable]
public string Country { get; set; }
}
}
Bu sınıf, Birleşik Devletler veya Kanada'daki adresleri açıklamak için kullanılan standart değerleri içerir. Dizinde mantıksal alanları birlikte gruplandırmak için bunun gibi türleri kullanabilirsiniz.
Rooms
özelliği bir nesne dizisini Room
temsil eder:
using System;
using Microsoft.Azure.Search;
using Microsoft.Azure.Search.Models;
using Newtonsoft.Json;
namespace AzureSearch.SDKHowTo
{
public partial class Room
{
[IsSearchable]
[Analyzer(AnalyzerName.AsString.EnMicrosoft)]
public string Description { get; set; }
[IsSearchable]
[Analyzer(AnalyzerName.AsString.FrMicrosoft)]
[JsonProperty("Description_fr")]
public string DescriptionFr { get; set; }
[IsSearchable, IsFilterable, IsFacetable]
public string Type { get; set; }
[IsFilterable, IsFacetable]
public double? BaseRate { get; set; }
[IsSearchable, IsFilterable, IsFacetable]
public string BedOptions { get; set; }
[IsFilterable, IsFacetable]
public int SleepsCount { get; set; }
[IsFilterable, IsFacetable]
public bool? SmokingAllowed { get; set; }
[IsSearchable, IsFilterable, IsFacetable]
public string[] Tags { get; set; }
}
}
.NET'teki veri modeliniz ve buna karşılık gelen dizin şeması, son kullanıcınıza vermek istediğiniz arama deneyimini destekleyecek şekilde tasarlanmalıdır. .NET'teki her üst düzey nesne, yani dizindeki belge, kullanıcı arabiriminizde sunacağınız bir arama sonucuna karşılık gelir. Örneğin, bir otel arama uygulamasında son kullanıcılarınız otel adına, otelin özelliklerine veya belirli bir odanın özelliklerine göre arama yapmak isteyebilir. Biraz sonra bazı sorgu örneklerini ele alacağız.
Dizindeki belgelerle etkileşime geçmek için kendi sınıflarınızı kullanma özelliği her iki yönde de çalışır; Ayrıca, sonraki bölümde göreceğimiz gibi arama sonuçlarını alabilir ve SDK'nın bunları otomatik olarak istediğiniz türde seri durumdan çıkarabilmesini sağlayabilirsiniz.
Not
Azure Bilişsel Arama .NET SDK'sı, alan adlarının alan değerlerine Document
anahtar/değer eşlemesi olan sınıfını kullanarak dinamik olarak yazılan belgeleri de destekler. Bu durum, tasarım sırasında dizin şemasını bilmediğiniz veya belirli model sınıflarına bağlamanın kullanışlı olmayacağı senaryolarda kullanışlıdır. SDK'da belgelerle ilgili tüm yöntemler, Document
sınıfıyla çalışan aşırı yüklerin yanı sıra genel türde bir parametre alan kesin tür belirtilmiş aşırı yüklere de sahiptir. Bu öğreticideki örnek kodda yalnızca ikincisi kullanılır. Document
sınıfı öğesinden Dictionary<string, object>
devralır.
Neden boş değer atanabilir türleri kullanmalısınız?
kendi model sınıflarınızı bir Azure Bilişsel Arama dizinine eşlenecek şekilde tasarlarken ve int
gibi bool
değer türlerinin özelliklerini null atanabilir (örneğin, bool?
yerinebool
) bildirmenizi öneririz. Boş değer atanamayan bir özellik kullanırsanız buna karşılık gelen alan için dizininizdeki hiçbir belgenin boş bir değer içermediğini garanti etmeniz gerekir. Sdk veya Azure Bilişsel Arama hizmeti bunu zorunlu kılmanıza yardımcı olmaz.
Bu yalnızca kuramsal bir sorun değildir: Var olan Edm.Int32
türünde bir dizine yeni bir alan eklediğiniz bir senaryoyu düşünün. Dizin tanımını güncelleştirdikten sonra, tüm belgeler bu yeni alan için null değere sahip olur (tüm türler Azure Bilişsel Arama null değere sahip olduğundan). Ardından bu alan için boş değer atanamayan bir int
özelliğiyle bir model sınıfı kullanırsanız belgeleri almaya çalışırken bunun gibi bir JsonSerializationException
alırsınız:
Error converting value {null} to type 'System.Int32'. Path 'IntValue'.
Bu nedenle, en iyi uygulama olarak model sınıflarınızda boş değer atanabilir türler kullanmanızı öneririz.
JSON.NET ile Özel Serileştirme
SDK, belgeleri seri hale getirme ve seri durumdan çıkarma için JSON.NET kullanır. Serileştirmeyi ve seri durumdan çıkarmayı gerekirse kendi JsonConverter
veya IContractResolver
tanımlayarak özelleştirebilirsiniz. Daha fazla bilgi için JSON.NET belgelerine bakın. Bu, uygulamanızdan var olan bir model sınıfını Azure Bilişsel Arama ve diğer daha gelişmiş senaryolarla kullanmak üzere uyarlamak istediğinizde yararlı olabilir. Örneğin, özel serileştirme ile şunları yapabilirsiniz:
- Model sınıfınızın belirli özelliklerini belge alanları olarak depolanmasını dahil edin veya hariç tutun.
- Kodunuzdaki özellik adları ile dizininizdeki alan adları arasında eşleme.
- Özellikleri belge alanlarına eşlemek için kullanılabilecek özel öznitelikler oluşturun.
GitHub üzerinde Azure Bilişsel Arama .NET SDK'sı için birim testlerinde özel serileştirme uygulama örneklerini bulabilirsiniz. Bu klasör iyi bir başlangıç noktasıdır. Özel serileştirme testleri tarafından kullanılan sınıfları içerir.
Dizinde belge arama
Örnek uygulamanın son adımı dizindeki bazı belgeleri aramaktır:
private static void RunQueries(ISearchIndexClient indexClient)
{
SearchParameters parameters;
DocumentSearchResult<Hotel> results;
Console.WriteLine("Search the entire index for the term 'motel' and return only the HotelName field:\n");
parameters =
new SearchParameters()
{
Select = new[] { "HotelName" }
};
results = indexClient.Documents.Search<Hotel>("motel", parameters);
WriteDocuments(results);
Console.Write("Apply a filter to the index to find hotels with a room cheaper than $100 per night, ");
Console.WriteLine("and return the hotelId and description:\n");
parameters =
new SearchParameters()
{
Filter = "Rooms/any(r: r/BaseRate lt 100)",
Select = new[] { "HotelId", "Description" }
};
results = indexClient.Documents.Search<Hotel>("*", parameters);
WriteDocuments(results);
Console.Write("Search the entire index, order by a specific field (lastRenovationDate) ");
Console.Write("in descending order, take the top two results, and show only hotelName and ");
Console.WriteLine("lastRenovationDate:\n");
parameters =
new SearchParameters()
{
OrderBy = new[] { "LastRenovationDate desc" },
Select = new[] { "HotelName", "LastRenovationDate" },
Top = 2
};
results = indexClient.Documents.Search<Hotel>("*", parameters);
WriteDocuments(results);
Console.WriteLine("Search the entire index for the term 'hotel':\n");
parameters = new SearchParameters();
results = indexClient.Documents.Search<Hotel>("hotel", parameters);
WriteDocuments(results);
}
Her sorgu yürütürken, bu yöntem ilk olarak yeni SearchParameters
bir nesne oluşturur. Bu nesne, sorgu için sıralama, filtreleme, sayfalama ve model oluşturma gibi ek seçenekleri belirtmek için kullanılır. Bu yöntemde, farklı sorgular için , Select
, OrderBy
ve Top
özelliğini ayarlıyoruzFilter
. SearchParameters
Tüm özellikler burada belgelenmiştir.
Sonraki adım, arama sorgusunu gerçekten yürütmektir. Arama çalıştırılırken yöntemi kullanılır Documents.Search
. Her sorgu için, dize olarak kullanılacak arama metnini (veya "*"
arama metni yoksa) ve daha önce oluşturulan arama parametrelerini geçiririz. Ayrıca, SDK'ya arama sonuçlarındaki belgeleri türündeki nesneler halinde seri durumdan çıkaracağını bildiren için tür Hotel
parametresi Documents.Search
olarak da belirtirizHotel
.
Not
Arama sorgusu ifadesi söz dizimi hakkında daha fazla bilgiyi burada bulabilirsiniz.
Son olarak, her sorgudan sonra bu yöntem arama sonuçlarındaki tüm eşleşmeleri yineler ve her belgeyi konsola yazdırarak:
private static void WriteDocuments(DocumentSearchResult<Hotel> searchResults)
{
foreach (SearchResult<Hotel> result in searchResults.Results)
{
Console.WriteLine(result.Document);
}
Console.WriteLine();
}
Şimdi sorguların her birine daha yakından bakalım. İlk sorguyu yürütmek için kod aşağıdadır:
parameters =
new SearchParameters()
{
Select = new[] { "HotelName" }
};
results = indexClient.Documents.Search<Hotel>("motel", parameters);
WriteDocuments(results);
Bu durumda, aranabilir herhangi bir alanda dizinin tamamında "motel" sözcüğünü arıyoruz ve yalnızca parametresi tarafından Select
belirtildiği gibi otel adlarını almak istiyoruz. Sonuçlar şunlardır:
Name: Secret Point Motel
Name: Twin Dome Motel
Sonraki sorgu biraz daha ilginçtir. Gecelik fiyatı 100 ABD dolarından az olan bir oda olan tüm otelleri bulmak ve yalnızca otel kimliği ve açıklamasını döndürmek istiyoruz:
parameters =
new SearchParameters()
{
Filter = "Rooms/any(r: r/BaseRate lt 100)",
Select = new[] { "HotelId", "Description" }
};
results = indexClient.Documents.Search<Hotel>("*", parameters);
WriteDocuments(results);
Bu sorgu, Rooms/any(r: r/BaseRate lt 100)
dizindeki belgeleri filtrelemek için bir OData $filter
ifadesi kullanır. Bu, Rooms koleksiyonundaki her öğeye 'BaseRate lt 100' uygulamak için herhangi bir işleci kullanır. Azure Bilişsel Arama tarafından desteklenen OData söz dizimi hakkında daha fazla bilgi için buraya bakın.
Sorgunun sonuçları şunlardır:
HotelId: 1
Description: The hotel is ideally located on the main commercial artery of the city in the heart of New York...
HotelId: 2
Description: The hotel is situated in a nineteenth century plaza, which has been expanded and renovated to...
Ardından, en son yenilenmiş en iyi iki oteli bulmak ve otel adını ve son yenileme tarihini göstermek istiyoruz. Kod aşağıdaki gibidir:
parameters =
new SearchParameters()
{
OrderBy = new[] { "LastRenovationDate desc" },
Select = new[] { "HotelName", "LastRenovationDate" },
Top = 2
};
results = indexClient.Documents.Search<Hotel>("*", parameters);
WriteDocuments(results);
Bu durumda parametresini olarak lastRenovationDate desc
belirtmek için yine OData söz dizimini OrderBy
kullanırız. Ayrıca yalnızca ilk iki belgeyi aldığımızdan emin olmak için 2 olarak ayarlıyoruz Top
. Daha önce olduğu gibi hangi Select
alanların döndürüleceğini belirteceğiz.
Sonuçlar şunlardır:
Name: Fancy Stay Last renovated on: 6/27/2010 12:00:00 AM +00:00
Name: Roach Motel Last renovated on: 4/28/1982 12:00:00 AM +00:00
Son olarak, "otel" sözcüğüyle eşleşen tüm otel adlarını bulmak istiyoruz:
parameters = new SearchParameters()
{
SearchFields = new[] { "HotelName" }
};
results = indexClient.Documents.Search<Hotel>("hotel", parameters);
WriteDocuments(results);
Ayrıca, özelliği belirtmediğimiz Select
için tüm alanları içeren sonuçlar şunlardır:
HotelId: 3
Name: Triple Landscape Hotel
...
Bu adım öğreticiyi tamamlar ancak burada durmaz. **Sonraki adımlar, Azure Bilişsel Arama hakkında daha fazla bilgi edinmek için ek kaynaklar sağlar.
Sonraki adımlar
- .NET SDK ve REST API başvurularına göz atın.
- Çeşitli nesneleri adlandırma kurallarını öğrenmek için adlandırma kurallarını gözden geçirin.
- Azure Bilişsel Arama'de desteklenen veri türlerini gözden geçirin.