Azure AI Search'te karmaşık veri türlerini modelleme

Azure AI Search dizinini doldurmak için kullanılan dış veri kümeleri birçok şekilde gelebilir. Bazen hiyerarşik veya iç içe alt yapılar içerirler. Örnekler arasında tek bir müşteri için birden çok adres, tek bir SKU için birden çok renk ve boyut, tek bir kitabın birden çok yazarı vb. olabilir. Modelleme terimlerinde bu yapıların karmaşık, bileşik, bileşik veya toplama veri türleri olarak anılan olduğunu görebilirsiniz. Azure AI Search'in bu kavram için kullandığı terim karmaşık türdür. Azure AI Search'te karmaşık türler karmaşık alanlar kullanılarak modellenir. Karmaşık alan, diğer karmaşık türler de dahil olmak üzere herhangi bir veri türünde olabilecek alt öğeleri (alt alanları) içeren bir alandır. Bu, bir programlama dilindeki yapılandırılmış veri türlerine benzer şekilde çalışır.

Karmaşık alanlar, veri türüne bağlı olarak belgedeki tek bir nesneyi veya bir nesne dizisini temsil eder. Türdeki Edm.ComplexType alanlar tek nesneleri, türdeki Collection(Edm.ComplexType) alanlar ise nesne dizilerini temsil eder.

Azure AI Search, karmaşık türleri ve koleksiyonları yerel olarak destekler. Bu türler, Azure AI Search dizinindeki neredeyse tüm JSON yapılarını modellemenizi sağlar. Azure AI Arama API'lerinin önceki sürümlerinde yalnızca düzleştirilmiş satır kümeleri içeri aktarılabiliyordu. En yeni sürümde dizininiz artık kaynak verilere daha yakın olabilir. Başka bir deyişle, kaynak verilerinizin karmaşık türleri varsa, dizininizin karmaşık türleri de olabilir.

Başlamak için, Azure portalındaki Verileri içeri aktarma sihirbazında yükleyebileceğiniz Oteller veri kümesini öneririz. Sihirbaz, kaynaktaki karmaşık türleri algılar ve algılanan yapıları temel alan bir dizin şeması önerir.

Not

karmaşık türler için destek, uygulamasından api-version=2019-05-06başlayarak genel kullanıma sunuldu.

Arama çözümünüz bir koleksiyondaki düzleştirilmiş veri kümelerinin önceki geçici çözümlerini temel alıyorsa, dizininizi en yeni API sürümünde desteklenen karmaşık türleri içerecek şekilde değiştirmeniz gerekir. API sürümlerini yükseltme hakkında daha fazla bilgi için bkz . En yeni REST API sürümüne yükseltme veya En yeni .NET SDK sürümüne yükseltme.

Karmaşık yapı örneği

Aşağıdaki JSON belgesi basit alanlardan ve karmaşık alanlardan oluşur. ve Roomsgibi Address karmaşık alanların alt alanları vardır. Address belgedeki tek bir nesne olduğundan bu alt alanlar için tek bir değer kümesine sahiptir. Buna karşılık, Rooms alt alanları için, koleksiyondaki her nesne için bir değer kümesi olan birden çok değer kümesi vardır.

{
  "HotelId": "1",
  "HotelName": "Secret Point Motel",
  "Description": "Ideally located on the main commercial artery of the city in the heart of New York.",
  "Tags": ["Free wifi", "on-site parking", "indoor pool", "continental breakfast"],
  "Address": {
    "StreetAddress": "677 5th Ave",
    "City": "New York",
    "StateProvince": "NY"
  },
  "Rooms": [
    {
      "Description": "Budget Room, 1 Queen Bed (Cityside)",
      "RoomNumber": 1105,
      "BaseRate": 96.99,
    },
    {
      "Description": "Deluxe Room, 2 Double Beds (City View)",
      "Type": "Deluxe Room",
      "BaseRate": 150.99,
    }
    . . .
  ]
}

Karmaşık türleri dizinleme

Dizin oluşturma sırasında, tek bir belgedeki tüm karmaşık koleksiyonlarda en fazla 3000 öğeye sahip olabilirsiniz. Karmaşık bir koleksiyonun öğesi bu koleksiyonun bir üyesidir, bu nedenle Odalar söz konusu olduğunda (Otel örneğindeki tek karmaşık koleksiyon), her oda bir öğedir. Yukarıdaki örnekte, "Gizli Nokta Moteli" 500 odalıysa, otel belgesinde 500 oda öğesi olacaktır. İç içe yerleştirilmiş karmaşık koleksiyonlar için iç içe her öğe, dış (üst) öğeye ek olarak sayılır.

Bu sınır yalnızca karmaşık koleksiyonlar için geçerlidir ve karmaşık türler (Adres gibi) veya dize koleksiyonları (Etiketler gibi) için geçerli değildir.

Karmaşık alanlar oluşturma

Herhangi bir dizin tanımında olduğu gibi portal, REST API veya .NET SDK'sını kullanarak karmaşık türler içeren bir şema oluşturabilirsiniz.

Diğer Azure SDK'ları Python, Java ve JavaScript'te örnekler sağlar.

  1. Azure Portal’ında oturum açın.

  2. Arama hizmetine Genel Bakış sayfasında Dizinler sekmesini seçin.

  3. Mevcut bir dizini açın veya yeni bir dizin oluşturun.

  4. Alanlar sekmesini ve ardından Alan ekle'yi seçin. Boş bir alan eklenir. Mevcut bir alan koleksiyonuyla çalışıyorsanız, alanı ayarlamak için aşağı kaydırın.

  5. Alana bir ad verin ve türünü veya Collection(Edm.ComplexType)olarak Edm.ComplexType ayarlayın.

  6. En sağdaki üç noktayı seçin ve ardından Alan ekle veya Alt alan ekle'yi seçin ve ardından öznitelikleri atayın.

Karmaşık alanları güncelleştirme

Genel olarak alanlara uygulanan tüm yeniden dizinleme kuralları yine de karmaşık alanlara uygulanır. Burada ana kuralların birkaçını bekleterek karmaşık bir türe alan eklemek için dizin yeniden derlemesi gerekmez, ancak çoğu değişiklik bunu yapar.

Tanımda yapısal güncelleştirmeler

Dizin yeniden derlemesine gerek kalmadan istediğiniz zaman karmaşık bir alana yeni alt alan ekleyebilirsiniz. Örneğin, dizinine "ZipCode" veya 'a Address "Olanaklar" eklemeye Rooms izin verilir, aynı dizine en üst düzey alan ekleme gibi. Mevcut belgeler, verilerinizi güncelleştirerek bu alanları açıkça doldurana kadar yeni alanlar için null değere sahiptir.

Karmaşık bir tür içinde her alt alanın bir türü olduğuna ve üst düzey alanlarda olduğu gibi özniteliklere sahip olabileceğine dikkat edin

Veri güncelleştirmeleri

Bir dizindeki mevcut belgeleri eylemle upload güncelleştirmek karmaşık ve basit alanlar için aynı şekilde çalışır: tüm alanlar değiştirilir. Ancak ( merge veya mergeOrUpload var olan bir belgeye uygulandığında) tüm alanlarda aynı şekilde çalışmaz. Özellikle, merge bir koleksiyon içindeki öğelerin birleştirilmesini desteklemez. Bu sınırlama, ilkel tür koleksiyonları ve karmaşık koleksiyonlar için mevcuttur. Bir koleksiyonu güncelleştirmek için tam koleksiyon değerini almanız, değişiklikler yapmanız ve ardından yeni koleksiyonu Dizin API'si isteğine eklemeniz gerekir.

Karmaşık alanlarda arama

Serbest biçimli arama ifadeleri karmaşık türlerde beklendiği gibi çalışır. Belgenin herhangi bir yerinde aranabilir alan veya alt alan eşleşiyorsa, belgenin kendisi bir eşleşmedir.

Birden çok teriminiz ve işleciniz olduğunda sorgular daha fazla ayrıntıya sahip olur ve lucene söz diziminde mümkün olduğu gibi bazı terimlerde alan adları belirtilir. Örneğin, bu sorgu "Portland" ve "OR" olmak üzere iki terimi Adres alanının iki alt alanıyla eşleştirmeye çalışır:

search=Address/City:Portland AND Address/State:OR

Bunun gibi sorgular , filtrelerin aksine tam metin araması için bağıntısızdır . Filtrelerde, karmaşık bir koleksiyonun alt alanları üzerindeki sorgular veya alliçindeki any aralık değişkenleri kullanılarak ilişkilendirilir. Yukarıdaki Lucene sorgusu, Oregon'daki diğer şehirlerle birlikte hem "Portland, Maine" hem de "Portland, Oregon" içeren belgeleri döndürür. Bunun nedeni, her yan tümcenin belgenin tamamında kendi alanının tüm değerlerine geçerli olmasıdır, dolayısıyla "geçerli alt belge" kavramı yoktur. Bu konuda daha fazla bilgi için bkz . Azure AI Search'te OData koleksiyon filtrelerini anlama.

Karmaşık alanları seçme

$select parametresi, arama sonuçlarında hangi alanların döndürüleceğini seçmek için kullanılır. Karmaşık bir alanın belirli alt alanlarını seçmek için bu parametreyi kullanmak için, üst alanı ve alt alanı eğik çizgi (/ ) ile ayırarak ekleyin.

$select=HotelName, Address/City, Rooms/BaseRate

Arama sonuçlarında yer almalarını istiyorsanız alanlar dizinde Alınabilir olarak işaretlenmelidir. Bir deyimde $select yalnızca Alınabilir olarak işaretlenmiş alanlar kullanılabilir.

Karmaşık alanları filtreleme, model ve sıralama

Filtreleme ve alanlı aramalar için kullanılan OData yolu söz dizimi , arama isteğindeki alanları modellemek, sıralamak ve seçmek için de kullanılabilir. Karmaşık türler için, sıralanabilir veya modellenebilir olarak işaretlenebilen alt alanları yöneten kurallar uygulanır. Bu kurallar hakkında daha fazla bilgi için bkz. Dizin API'si oluşturma başvurusu.

Yüz tanıma alt alanları

veya türünde Edm.GeographyPointCollection(Edm.GeographyPoint)olmadığı sürece herhangi bir alt alan modellenebilir olarak işaretlenebilir.

Model sonuçlarında döndürülen belge sayıları, karmaşık bir koleksiyondaki (odalar) alt belgeler için değil, üst belge (otel) için hesaplanır. Örneğin, bir otelin "suite" türünde 20 odası olduğunu varsayalım. Bu model parametresi facet=Rooms/Typegöz önüne alındığında, model sayısı odalar için 20 değil, otel için bir tanedir.

Karmaşık alanları sıralama

Sıralama işlemleri, alt belgelere (Odalar) değil belgelere (Oteller) uygulanır. Odalar gibi karmaşık bir tür koleksiyonunuz varsa, Odalar'a göre sıralayamazsınız. Aslında, herhangi bir koleksiyona göre sıralama yapamazsınız.

Alanların basit bir alan mı yoksa karmaşık türde bir alt alan mı olduğu, alanlar belge başına tek bir değere sahip olduğunda sıralama işlemleri çalışır. Örneğin, Address/City otel başına yalnızca bir adres olduğundan sıralanabilir olabilir, bu nedenle $orderby=Address/City oteller şehre göre sıralanır.

Karmaşık alanlara göre filtreleme

Bir filtre ifadesindeki karmaşık alanın alt alanlarına başvurabilirsiniz. Alanları modellemek, sıralamak ve seçmek için kullanılan OData yolu söz dizimini kullanmanız gerekir. Örneğin, aşağıdaki filtre Kanada'daki tüm otelleri döndürür:

$filter=Address/Country eq 'Canada'

Karmaşık bir koleksiyon alanına filtre uygulamak için ve all işleçleriyle bir any lambda ifadesi kullanabilirsiniz. Bu durumda, lambda ifadesinin aralık değişkeni alt alanları olan bir nesnedir. Bu alt alanlara standart OData yolu söz dizimi ile başvurabilirsiniz. Örneğin, aşağıdaki filtre en az bir deluxe oda ve sigara içmeyen tüm odaları olan tüm otelleri döndürür:

$filter=Rooms/any(room: room/Type eq 'Deluxe Room') and Rooms/all(room: not room/SmokingAllowed)

Üst düzey basit alanlarda olduğu gibi, karmaşık alanların basit alt alanları yalnızca dizin tanımında filtrelenebilir özniteliği ayarlanmışsa filtrelere true eklenebilir. Daha fazla bilgi için bkz. Dizin API'sini oluşturma başvurusu.

Azure Search, tek bir belgedeki koleksiyonlardaki karmaşık nesnelerin 3000'i aşamayamayacağına ilişkin sınırlamaya sahiptir.

Kullanıcılar, karmaşık koleksiyonlar 3000 sınırını aştığında dizin oluşturma sırasında aşağıdaki hatayla karşılaşır.

"Belgenizdeki bir koleksiyon, tüm karmaşık koleksiyonlar sınırında en fazla öğe sınırını aşıyor. '1052' anahtarına sahip belgede koleksiyonlarda (JSON dizileri) '4303' nesneleri var. Belgenin tamamında en fazla '3000' nesnenin koleksiyonlarda yer alınmasına izin verilir. Koleksiyonlardan nesneleri kaldırın ve belgenin dizinini oluşturmayı yeniden deneyin."

Bazı kullanım örneklerinde koleksiyona 3000'den fazla öğe eklememiz gerekebilir. Bu kullanım örneklerinde, değerleri sınırlandırmak, birleştirmek ve sınırlandırılmış dize olarak depolamak için herhangi bir sınırlayıcı biçimini kullanabiliriz (|) veya kullanabiliriz. Azure Search'te bir dizide depolanan dizelerin sayısıyla ilgili bir sınırlama yoktur. Bu karmaşık değerleri dizeler olarak depolamak sınırlamayı önler. Müşterinin bu geçici çözümün senaryo gereksinimlerini karşılayıp karşılamadığını doğrulaması gerekir.

Örneğin, aşağıdaki "searchScope" dizisinde 3000'den fazla öğe varsa karmaşık türler kullanmak mümkün olmaz.


"searchScope": [
  {
     "countryCode": "FRA",
     "productCode": 1234,
     "categoryCode": "C100" 
  },
  {
     "countryCode": "USA",
     "productCode": 1235,
     "categoryCode": "C200" 
  }
]

Bu karmaşık değerleri sınırlayıcı ile dize olarak depolamak sınırlamayı önler

"searchScope": [
        "|FRA|1234|C100|",
        "|FRA|*|*|",
        "|*|1234|*|",
        "|*|*|C100|",
        "|FRA|*|C100|",
        "|*|1234|C100|"
]

Bunları joker karakterlerle depolamak yerine, depolama boyutunu kesmek için sözcüğü | olarak bölen özel bir çözümleyici de kullanabiliriz.

Değerleri aşağıdaki gibi depolamak yerine joker karakterlerle depolama nedenimiz

|FRA|1234|C100|

, ürün ve kategorilerden bağımsız olarak müşterinin Fransa ülkesi olan öğeleri aramak isteyebileceği arama senaryolarını karşılamaktır. Benzer şekilde, müşterinin ülke veya kategoriden bağımsız olarak öğenin 1234 ürününe sahip olup olmadığını görmek için araması gerekebilir.

Yalnızca bir girdi depolasaydık

|FRA|1234|C100|

joker karakterler olmadan, kullanıcı yalnızca Fransa'da filtrelemek istiyorsa, "searchScope" dizimizde Fransa'nın hangi bileşiminin mevcut olduğunu bilmediğimiz için kullanıcı girişini "searchScope" dizisiyle eşleşecek şekilde dönüştüremiyoruz

Kullanıcı yalnızca ülkeye göre filtrelemek istiyorsa, Diyelim ki Fransa. Kullanıcı girişini alacağız ve aşağıdaki gibi bir dize olarak oluşturacağız:

|FRA|*|*|

Bunu daha sonra bir öğe değerleri dizisinde arama yaptığımızda Azure Search'te filtrelemek için kullanabiliriz

foreach (var filterItem in filterCombinations)
        {
            var formattedCondition = $"searchScope/any(s: s eq '{filterItem}')";
            combFilter.Append(combFilter.Length > 0 ? " or (" + formattedCondition + ")" : "(" + formattedCondition + ")");
        }

Benzer şekilde, kullanıcı Fransa ve 1234 ürün kodunu ararsa kullanıcı girişini alır, aşağıdaki gibi sınırlandırılmış bir dize olarak oluşturur ve arama dizimizle eşleştiririz.

|FRA|1234|*|

Kullanıcı 1234 ürün kodunu ararsa, kullanıcı girişini alır, aşağıdaki gibi sınırlandırılmış bir dize olarak oluşturur ve arama dizimizle eşleştiririz.

|*|1234|*|

Kullanıcı C100 kategori kodunu ararsa kullanıcı girişini alır, aşağıdaki gibi sınırlandırılmış bir dize olarak oluşturur ve arama dizimizle eşleştiririz.

|*|*|C100|

Kullanıcı Fransa ve 1234 ürün kodu ile C100 kategori kodunu ararsa kullanıcı girişini alır, aşağıda gösterildiği gibi sınırlandırılmış bir dize olarak oluşturur ve arama dizimizle eşleştiririz.

|FRA|1234|C100|

Bir kullanıcı listemizde bulunmayan ülkeleri aramaya çalışırsa, arama dizininde depolanan sınırlandırılmış "searchScope" dizisiyle eşleşmez ve sonuç döndürülmeyecektir. Örneğin, bir kullanıcı Kanada'yı ve 1234 ürün kodunu arar. Kullanıcı araması şu şekilde dönüştürülebilir:

|CAN|1234|*|

Bu, arama dizinimizdeki sınırlandırılmış dizideki girdilerden hiçbiri ile eşleşmez.

Yalnızca yukarıdaki tasarım seçimi için bu joker karakter girişi gerekir; karmaşık bir nesne olarak kaydedilmişse, aşağıda gösterildiği gibi açık bir arama gerçekleştirebilirdik.

           var countryFilter = $"searchScope/any(ss: search.in(countryCode ,'FRA'))";
            var catgFilter = $"searchScope/any(ss: search.in(categoryCode ,'C100'))";
            var combinedCountryCategoryFilter = "(" + countryFilter + " and " + catgFilter + ")";

Bu nedenle, karmaşık koleksiyonlarımız Azure Search sınırını aşarsa, değerleri karmaşık bir koleksiyon yerine sınırlandırılmış dize olarak depolayarak bir değer bileşimini aramamız gereken gereksinimleri karşılayabiliriz. Bu, geçici çözümlerden biridir ve müşterinin senaryo gereksinimlerini karşılayıp karşılamayacağını doğrulaması gerekir.

Sonraki adımlar

Verileri içeri aktarma sihirbazında Oteller veri kümesini deneyin. Verilere erişmek için benioku dosyasında sağlanan Azure Cosmos DB bağlantı bilgilerine ihtiyacınız vardır.

Bu bilgiler elinizde olduğunda sihirbazdaki ilk adımınız yeni bir Azure Cosmos DB veri kaynağı oluşturmaktır. Sihirbazın devamında, hedef dizin sayfasına gittiğinizde karmaşık türleri olan bir dizin görürsünüz. Bu dizini oluşturup yükleyin ve ardından yeni yapıyı anlamak için sorgular yürütün.