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 ürün 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-06
baş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 Rooms
gibi 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": "Stay-Kay City Hotel",
"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 alanlar oluşturma
Herhangi bir dizin tanımında olduğu gibi Azure portalını, REST API'yi 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.
Azure Portal’ında oturum açın.
Arama hizmetine Genel Bakış sayfasında Dizinler sekmesini seçin.
Mevcut bir dizini açın veya yeni bir dizin oluşturun.
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.
Alana bir ad verin ve türünü veya
Collection(Edm.ComplexType)
olarakEdm.ComplexType
ayarlayın.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 koleksiyon sınırları
Dizin oluşturma sırasında, tek bir belgedeki tüm karmaşık koleksiyonlarda en fazla 3.000 öğeye sahip olabilirsiniz. Karmaşık bir koleksiyonun öğesi, bu koleksiyonun bir üyesidir. Odalar (Otel örneğindeki tek karmaşık koleksiyon) için her oda bir öğedir. Yukarıdaki örnekte , "Stay-Kay City Hotel" 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ı güncelleştirme
Genel olarak alanlara uygulanan tüm yeniden dizinleme kuralları yine de karmaşık alanlara uygulanır. Karmaşık bir türe yeni alan eklemek için dizin yeniden derlemesi gerekmez, ancak diğer değişikliklerin çoğu yeniden derleme gerektirir.
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.
Metin sorgularında karmaşık alanları 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 all
iç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.
RAG sorgularında karmaşık alanları arama
RAG deseni, oluşturmalı yapay zeka ve konuşma araması için arama sonuçlarını bir sohbet modeline geçirir. Varsayılan olarak, LLM'ye geçirilen arama sonuçları düzleştirilmiş bir satır kümesidir. Ancak dizininizde karmaşık türler varsa, arama sonuçlarını önce JSON'a dönüştürdüyseniz ve ardından JSON'yi LLM'ye geçirirseniz sorgunuz bu alanları sağlayabilir.
Kısmi bir örnek tekniği gösterir:
- İstemde veya sorguda istediğiniz alanları belirtin
- Alanların dizinde aranabilir ve alınabilir olduğundan emin olun
- Arama sonuçları için alanları seçin
- Sonuçları JSON olarak biçimlendirme
- Sohbet tamamlama isteğini model sağlayıcısına gönderme
import json
# Query is the question being asked. It's sent to the search engine and the LLM.
query="Can you recommend a few hotels that offer complimentary breakfast? Tell me their description, address, tags, and the rate for one room they have which sleep 4 people."
# Set up the search results and the chat thread.
# Retrieve the selected fields from the search index related to the question.
selected_fields = ["HotelName","Description","Address","Rooms","Tags"]
search_results = search_client.search(
search_text=query,
top=5,
select=selected_fields,
query_type="semantic"
)
sources_filtered = [{field: result[field] for field in selected_fields} for result in search_results]
sources_formatted = "\n".join([json.dumps(source) for source in sources_filtered])
response = openai_client.chat.completions.create(
messages=[
{
"role": "user",
"content": GROUNDED_PROMPT.format(query=query, sources=sources_formatted)
}
],
model=AZURE_DEPLOYMENT_MODEL
)
print(response.choices[0].message.content)
Uçtan uca örnek için bkz . Hızlı Başlangıç: Azure AI Search'ten topraklama verileri içeren oluşturmalı arama (RAG).
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.GeographyPoint
Collection(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/Type
gö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.
Karmaşık koleksiyon sınırı için geçici çözüm
Azure AI Search'in bir koleksiyondaki karmaşık nesneleri belge başına 3.000 nesneyle sınırladığını hatırlayın. Bu sınırın aşılması aşağıdaki iletiyi döndürür:
A collection in your document exceeds the maximum elements across all complex collections limit.
The document with key '1052' has '4303' objects in collections (JSON arrays).
At most '3000' objects are allowed to be in collections across the entire document.
Remove objects from collections and try indexing the document again."
3.000'den fazla öğeye ihtiyacınız varsa, 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çimi kullanabilirsiniz (|
) veya kullanabilirsiniz. Bir dizide depolanan dizelerin sayısıyla ilgili bir sınırlama yoktur. Karmaşık değerleri dizeler olarak depolamak karmaşık koleksiyon sınırlamasını atlar.
Göstermek için, 3.000'den fazla öğe içeren bir "searchScope
" diziniz olduğunu varsayalım:
"searchScope": [
{
"countryCode": "FRA",
"productCode": 1234,
"categoryCode": "C100"
},
{
"countryCode": "USA",
"productCode": 1235,
"categoryCode": "C200"
}
. . .
]
Değerleri sınırlandırılmış dize olarak depolamaya yönelik geçici çözüm şu şekilde görünebilir:
"searchScope": [
"|FRA|1234|C100|",
"|FRA|*|*|",
"|*|1234|*|",
"|*|*|C100|",
"|FRA|*|C100|",
"|*|1234|C100|"
]
Tüm arama değişkenlerini sınırlandırılmış dizede depolamak, yalnızca "FRA" veya "1234" veya dizi içinde başka bir bileşimi olan öğeleri aramak istediğiniz arama senaryolarında yararlıdır.
C# dilinde girişleri aranabilir dizelere dönüştüren bir filtre biçimlendirme parçacığı aşağıdadır:
foreach (var filterItem in filterCombinations)
{
var formattedCondition = $"searchScope/any(s: s eq '{filterItem}')";
combFilter.Append(combFilter.Length > 0 ? " or (" + formattedCondition + ")" : "(" + formattedCondition + ")");
}
Aşağıdaki listede yan yana girişler ve arama dizeleri (çıkışlar) sağlanır:
"FRA" ilçe kodu ve "1234" ürün kodu için biçimlendirilmiş çıkış şeklindedir
|FRA|1234|*|
."1234" ürün kodu için biçimlendirilmiş çıkış şeklindedir
|*|1234|*|
."C100" kategori kodu için biçimlendirilmiş çıkış şeklindedir
|*|*|C100|
.
Joker karakteri (*
) yalnızca dize dizisi geçici çözümünü uyguluyorsanız sağlayın. Aksi takdirde, karmaşık bir tür kullanıyorsanız filtreniz şu örnekteki gibi görünebilir:
var countryFilter = $"searchScope/any(ss: search.in(countryCode ,'FRA'))";
var catgFilter = $"searchScope/any(ss: search.in(categoryCode ,'C100'))";
var combinedCountryCategoryFilter = "(" + countryFilter + " and " + catgFilter + ")";
Geçici çözümü uygularsanız, kapsamlı bir şekilde test etmeye özen gösterin.
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.