Aracılığıyla paylaş


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.Searchdiğ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ın Microsoft.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ın Microsoft.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 Indexsınıfların Documentyanı sıra ve SearchIndexClient sınıflarında SearchServiceClient ve Documents.Search gibi Indexes.Create işlemleri Fieldtanı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

  1. Visual Studio 2017 veya üzeri.
  2. 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.
  3. 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 SearchServiceClientbir 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.Createilk 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 SearchIndexClientgerekir. 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 SearchCredentialssağ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 SearchIndexClientgö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ı SearchIndexClientbir kullanırız:

ISearchIndexClient indexClientForQueries = CreateSearchIndexClient(indexName, configuration);

RunQueries(indexClientForQueries);

Yöntemi daha sonra daha yakından inceleyeceğiz RunQueries . Yeni SearchIndexClientoluş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 Mainyöntemlerin her birine daha yakından bakacağız.

Dizin oluşturma

oluşturduktan SearchServiceClientsonra , 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 DeleteAsyncDeletekullanabilirsinizExistsAsync.

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.Uploadyaparak 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.MergeOrUploadIndexBatch.Delete çağırarak IndexBatch.Mergetoplu 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.Newfarklı işlemleri tek bir toplu işlemde karıştırabilirsiniz. , ve gibi IndexAction.MergeIndexAction.Uploadilgili 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 Indexbaş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, Keyve Analyzergibi 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.BooleanDateTimeOffset?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 IContractResolvertanı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, OrderByve 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 Hotelparametresi Documents.Searcholarak 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 descbelirtmek 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