OData koleksiyon filtrelerinin Azure AI Search'te nasıl çalıştığını anlama
Bu makale, karmaşık lambda ifadeleriyle gelişmiş filtreler yazan geliştiriciler için arka plan sağlar. Bu makalede, Azure AI Search'ün bu filtreleri nasıl yürüttüğüne bakarak koleksiyon filtreleri kurallarının neden mevcut olduğu açıklanmaktadır.
Azure AI Search'te koleksiyon alanları için bir filtre oluşturduğunuzda ve all
işleçlerini lambda ifadeleriyle birlikte kullanabilirsiniz.any
Lambda ifadeleri, bir aralık değişkenine başvuran Boole ifadeleridir. Lambda ifadesi kullanan filtrelerde ve all
işleçleri çoğu any
programlama dilinde bir for
döngüye benzer; aralık değişkeni döngü değişkeninin rolünü alır ve lambda ifadesi döngünün gövdesi olarak kullanılır. Aralık değişkeni, döngünün yinelenmesi sırasında koleksiyonun "geçerli" değerini alır.
En azından kavramsal olarak bu şekilde çalışır. Gerçekte Azure AI Search, döngülerin çalışma for
şekline çok farklı bir şekilde filtre uygular. İdeal olarak, bu fark sizin için görünmez, ancak bazı durumlarda görünmez. Sonuç olarak lambda ifadeleri yazarken izlemeniz gereken kurallar vardır.
Not
Örnekler de dahil olmak üzere koleksiyon filtreleri kurallarının ne olduğu hakkında bilgi için bkz . Azure AI Search'te OData koleksiyonu filtrelerinde sorun giderme.
Koleksiyon filtreleri neden sınırlıdır?
Filtre özelliklerinin tüm koleksiyon türleri için tam olarak desteklenmemelerinin temel üç nedeni vardır:
- Belirli veri türleri için yalnızca belirli işleçler desteklenir. Örneğin, Boole değerlerini
true
karşılaştırmak vefalse
,gt
vb. kullanmaklt
mantıklı değildir. - Azure AI Search türündeki
Collection(Edm.ComplexType)
alanlarda bağıntılı aramayı desteklemez. - Azure AI Search, koleksiyonlar da dahil olmak üzere tüm veri türleri üzerinde filtre yürütmek için ters dizinler kullanır.
İlk neden, OData dili ve EDM tür sisteminin nasıl tanımlandığının bir sonucudur. Son ikisi bu makalenin geri kalanında daha ayrıntılı olarak açıklanmıştır.
Bağıntılı ve bağıntısız arama
Karmaşık nesnelerden oluşan bir koleksiyona birden çok filtre ölçütü uyguladığınızda, ölçütler koleksiyondaki her nesne için geçerli olduğundan bağıntılı olarak yapılır. Örneğin, aşağıdaki filtrede fiyatı 100'den az olan en az bir deluxe oda olan oteller döndürülüyor:
Rooms/any(room: room/Type eq 'Deluxe Room' and room/BaseRate lt 100)
Filtreleme bağıntısızsa, yukarıdaki filtre bir odanın deluxe olduğu ve farklı bir odanın taban fiyatı 100'den az olan otelleri döndürebilir. Lambda ifadesinin her iki yan tümcesi aynı aralık değişkenine (yani room
) uygulandığından bu mantıklı olmaz. Bu nedenle bu tür filtreler bağıntılı.
Ancak, tam metin araması için belirli bir aralık değişkenine başvurmanın hiçbir yolu yoktur. Bunun gibi tam bir Lucene sorgusu vermek için alanlı arama kullanıyorsanız:
Rooms/Type:deluxe AND Rooms/Description:"city view"
bir odanın deluxe olduğu ve farklı bir odanın açıklamasında "şehir görünümünden" bahsedildiği oteller alabilirsiniz. Örneğin, aşağıdaki ile belge Id
1
sorguyla eşleşer:
{
"value": [
{
"Id": "1",
"Rooms": [
{ "Type": "deluxe", "Description": "Large garden view suite" },
{ "Type": "standard", "Description": "Standard city view room" }
]
},
{
"Id": "2",
"Rooms": [
{ "Type": "deluxe", "Description": "Courtyard motel room" }
]
}
]
}
Bunun nedeni, Rooms/Type
aşağıdaki tablolarda gösterildiği gibi, belgenin tamamında alanın tüm analiz edilen terimlerine Rooms/Type
ve benzer şekilde için Rooms/Description
ifade edilir.
Tam metin araması için nasıl Rooms/Type
depolanır:
Terim: Rooms/Type |
Belge Kimlikleri |
---|---|
Deluxe | 1, 2 |
standart | 1 |
Tam metin araması için nasıl Rooms/Description
depolanır:
Terim: Rooms/Description |
Belge Kimlikleri |
---|---|
avlu | 2 |
şehir | 1 |
bahçe | 1 |
büyük | 1 |
motel | 2 |
oda | 1, 2 |
standart | 1 |
maiyet | 1 |
görünüm | 1 |
Bu nedenle, temelde "bir odanın 'Deluxe Oda'ya eşit olduğu ve aynı odanın Type
BaseRate
100'den az olduğu belgeleri eşleştir" yazan yukarıdaki filtreden farklı olarak, arama sorgusu "deluxe" terimine sahip olan ve Rooms/Description
"şehir görünümü" ifadesini içeren belgeleri Rooms/Type
eşleştir ifadesini içerir. İkinci durumda alanları bağıntılı olabilecek tek tek odalar kavramı yoktur.
Ters dizinler ve koleksiyonlar
Karmaşık koleksiyonlar üzerinde lambda ifadelerinde , Collection(Edm.GeographyPoint)
gibi Collection(Edm.Int32)
basit koleksiyonlara göre çok daha az kısıtlama olduğunu fark etmiş olabilirsiniz. Bunun nedeni Azure AI Search'ün karmaşık koleksiyonları gerçek alt belge koleksiyonları olarak depolaması, basit koleksiyonların ise hiç koleksiyon olarak depolanmamalarından kaynaklanır.
Örneğin, çevrimiçi bir satıcı için dizindeki gibi seasons
filtrelenebilir bir dize koleksiyonu alanını göz önünde bulundurun. Bu dizine yüklenen bazı belgeler aşağıdaki gibi görünebilir:
{
"value": [
{
"id": "1",
"name": "Hiking boots",
"seasons": ["spring", "summer", "fall"]
},
{
"id": "2",
"name": "Rain jacket",
"seasons": ["spring", "fall", "winter"]
},
{
"id": "3",
"name": "Parka",
"seasons": ["winter"]
}
]
}
Alanının değerleriseasons
, aşağıdakine benzer şekilde ters dizin adı verilen bir yapıda depolanır:
Süre | Belge Kimlikleri |
---|---|
ilkbahar | 1, 2 |
yaz | 1 |
sonbahar | 1, 2 |
kış | 2, 3 |
Bu veri yapısı tek bir soruyu büyük bir hızla yanıtlamak için tasarlanmıştır: Belirli bir terim hangi belgelerde görünür? Bu soruyu yanıtlamak, bir koleksiyon üzerindeki döngüden daha çok düz eşitlik denetimi gibi çalışır. Aslında, bu nedenle Dize koleksiyonları için Azure AI Search yalnızca için any
bir lambda ifadesinin içinde karşılaştırma işleci olarak izin verireq
.
Ardından, aynı aralık değişkeninde birden çok eşitlik denetimini ile or
birleştirmenin nasıl mümkün olduğunu inceleyeceğiz. Cebir ve niceleyicilerin dağıtıcı özelliği sayesinde çalışır. Bu ifade:
seasons/any(s: s eq 'winter' or s eq 'fall')
eşdeğerdir:
seasons/any(s: s eq 'winter') or seasons/any(s: s eq 'fall')
ve iki any
alt ifadenin her biri, ters çevrilmiş dizin kullanılarak verimli bir şekilde yürütülebilir. Ayrıca, niceleyicilerin olumsuzlama yasası sayesinde şu ifade:
seasons/all(s: s ne 'winter' and s ne 'fall')
eşdeğerdir:
not seasons/any(s: s eq 'winter' or s eq 'fall')
bu nedenle ve and
ile ne
kullanmak all
mümkündür.
Not
Ayrıntılar bu belgenin kapsamı dışında olsa da, bu ilkeler coğrafi uzamsal nokta koleksiyonları için mesafe ve kesişim testlerine de uzanır. bu nedenle, içinde any
:
geo.intersects
iptal edilemiyorgeo.distance
veya kullanılaraklt
karşılaştırılmalıdırle
- ifadeler ile
or
birleştirilmeli, ile birleştirilmemelidirand
Tersi kurallar için all
geçerlidir.
Örneğin, , le
gt
, ve ge
işleçlerini destekleyen lt
veri türleri koleksiyonları filtrelenirken çok çeşitli ifadelere Collection(Edm.Int32)
izin verilir. Özellikle, temel alınan karşılaştırma ifadeleri kullanılarak aralık karşılaştırmaları halinde birleştirildiği ve daha sonra kullanılarak or
daha fazla birleştirildiği sürece içinde de kullanabilirsiniz any
and
or
.and
Boole ifadelerinin bu yapısına Ayrık Normal Form (DNF) adı verilir ve diğer adıyla "AND'lerin OR'leri". Buna karşılık, bu veri türleri için all
lambda ifadeleri Konjonktif Normal Formda (CNF) olmalıdır, aksi takdirde "OR'lerin AND'leri" olarak bilinir. Azure AI Search bu tür aralık karşılaştırmalarına izin verir çünkü dizeler için hızlı terim araması yapabilmesi gibi ters dizinleri kullanarak bunları verimli bir şekilde yürütebilir.
Özetle, lambda ifadesinde izin verilenler için temel kurallar şunlardır:
- içinde
any
, eşitlik, aralık karşılaştırmaları gibi pozitif denetimleregeo.intersects
her zaman izin verilir veyageo.distance
veyale
ilelt
karşılaştırılır (mesafe denetimi söz konusu olduğunda "yakınlığı" eşitlik gibi düşünün). or
içindeany
her zaman izin verilir. Yalnızca aralık denetimlerini ifade abilen veri türleri için ve yalnızca AND'lerin OR'lerini (DNF) kullanıyorsanız kullanabilirsinizand
.- içinde
all
kurallar tersine çevrilir. Yalnızca negatif denetimlere izin verilir, her zaman kullanabilirsinizand
ve yalnızca OR'lerin AND'leri (CNF) olarak ifade edilen aralık denetimleri için kullanabilirsinizor
.
Pratikte, yine de kullanma olasılığınız en yüksek olan filtre türleri bunlardır. Yine de mümkün olanın sınırlarını anlamak yararlı olabilir.
İzin verilen ve izin verilmeyen filtre türlerine ilişkin belirli örnekler için bkz . Geçerli koleksiyon filtreleri yazma.