Mevcut arama dizinine anlamsal derecelendirme eklemek için Azure.Search.Documents istemci kitaplığını kullanarak bir konsol uygulaması oluşturun.
Alternatif olarak, tamamlanmış bir projeyle başlamak için kaynak kodu indirebilirsiniz.
Ortamınızı ayarlama
Visual Studio'yu başlatın ve konsol uygulaması için yeni bir proje oluşturun.
Araçlar>NuGet Paket Yöneticisi Çözüm için NuGet Paketlerini Yönet... seçeneğini belirleyin.
Göz At'ı seçin.
Azure.Search.Documents paketini arayın ve en son kararlı sürümü seçin.
Derlemeyi projenize ve çözümünüze eklemek için Yükle'yi seçin.
Arama istemcisi oluşturma
Program.cs aşağıdaki using
yönergeleri ekleyin.
using Azure;
using Azure.Search.Documents;
using Azure.Search.Documents.Indexes;
using Azure.Search.Documents.Indexes.Models;
using Azure.Search.Documents.Models;
İki istemci oluşturma: SearchIndexClient dizini oluşturur ve SearchClient var olan bir dizini yükler ve sorgular.
Her iki istemcinin de oluşturma/silme haklarıyla kimlik doğrulaması için hizmet uç noktasına ve bir yönetici API anahtarına ihtiyacı vardır. Ancak, kod sizin için URI'yi oluşturur, bu nedenle özelliği için serviceName
yalnızca arama hizmeti adını belirtin. veya .search.windows.net
eklemeyinhttps://
.
static void Main(string[] args)
{
string serviceName = "<YOUR-SEARCH-SERVICE-NAME>";
string apiKey = "<YOUR-SEARCH-ADMIN-API-KEY>";
string indexName = "hotels-quickstart";
// Create a SearchIndexClient to send create/delete index commands
Uri serviceEndpoint = new Uri($"https://{serviceName}.search.windows.net/");
AzureKeyCredential credential = new AzureKeyCredential(apiKey);
SearchIndexClient adminClient = new SearchIndexClient(serviceEndpoint, credential);
// Create a SearchClient to load and query documents
SearchClient srchclient = new SearchClient(serviceEndpoint, indexName, credential);
. . .
}
Dizin oluşturma
Dizin şemasını oluşturarak veya güncelleştirerek ekleyin SemanticConfiguration
. Mevcut bir dizini güncelleştiriyorsanız, belgelerinizin yapısı değişmediğinden bu değişiklik için yeniden dizin oluşturma gerekmez.
// Create hotels-quickstart index
private static void CreateIndex(string indexName, SearchIndexClient adminClient)
{
FieldBuilder fieldBuilder = new FieldBuilder();
var searchFields = fieldBuilder.Build(typeof(Hotel));
var definition = new SearchIndex(indexName, searchFields);
var suggester = new SearchSuggester("sg", new[] { "HotelName", "Category", "Address/City", "Address/StateProvince" });
definition.Suggesters.Add(suggester);
definition.SemanticSearch = new SemanticSearch
{
Configurations =
{
new SemanticConfiguration("my-semantic-config", new()
{
TitleField = new SemanticField("HotelName"),
ContentFields =
{
new SemanticField("Description"),
new SemanticField("Description_fr")
},
KeywordsFields =
{
new SemanticField("Tags"),
new SemanticField("Category")
}
})
}
};
adminClient.CreateOrUpdateIndex(definition);
}
Aşağıdaki kod, arama hizmetinizde dizini oluşturur:
// Create index
Console.WriteLine("{0}", "Creating index...\n");
CreateIndex(indexName, adminClient);
SearchClient ingesterClient = adminClient.GetSearchClient(indexName);
Belge yükleme
Azure AI Search, hizmette depolanan içerik üzerinde aramalar. Belgeleri karşıya yükleme kodu, tam metin araması için C# hızlı başlangıcıyla aynıdır, bu nedenle belgeyi burada yinelememiz gerekmez. Adları, adresleri ve açıklamaları olan dört otel olmalıdır. Çözümünüz Oteller ve Adresler türlerine sahip olmalıdır.
Dizin arama
Parametreleri belirtmek için arama seçenekleriyle birlikte anlam derecesini çağıran bir sorgu aşağıdadır:
Console.WriteLine("Example of a semantic query.");
options = new SearchOptions()
{
QueryType = Azure.Search.Documents.Models.SearchQueryType.Semantic,
SemanticSearch = new()
{
SemanticConfigurationName = "my-semantic-config",
QueryCaption = new(QueryCaptionType.Extractive)
}
};
options.Select.Add("HotelName");
options.Select.Add("Category");
options.Select.Add("Description");
// response = srchclient.Search<Hotel>("*", options);
response = srchclient.Search<Hotel>("what hotel has a good restaurant on site", options);
WriteDocuments(response);
Karşılaştırma için, terim sıklığına ve yakınlığına göre varsayılan BM25 derecelendirmesini kullanan bir sorgunun sonuçları aşağıdadır. "Hangi otelin sitede iyi bir restoranı var" sorgusu göz önüne alındığında, BM25 derecelendirme algoritması eşleşmeleri bu ekran görüntüsünde gösterilen sırayla döndürür:
Buna karşılık, aynı sorguya semantik derecelendirme uygulandığında ("hangi otelin yerinde iyi bir restoranı vardır"), sonuçlar sorguyla anlamsal ilgisine göre yeniden düzenlenir. Bu kez en önemli sonuç, kullanıcı beklentilerine daha iyi uyum sağlayan restoranlı oteldir.
Programı çalıştırma
Uygulamayı yeniden derlemek ve programı tamamen çalıştırmak için F5 tuşuna basın.
Çıktı, sorgu bilgilerinin ve sonuçların eklenmesiyle birlikte Console.WriteLine'dan gelen iletileri içerir.
Anlam derecelendirmesi hakkında bilgi edinmek için Bir Jupyter not defteri ve Python için Azure SDK'daki azure-search-documents kitaplığını kullanın.
Alternatif olarak, tamamlanmış bir not defterini indirip çalıştırabilirsiniz.
Ortamınızı ayarlama
Python uzantısıyla Visual Studio Code veya Python 3.10 veya üzeri ile eşdeğer IDE kullanın.
Bu hızlı başlangıç için bir sanal ortam öneririz:
Visual Studio Code’u başlatın.
Yeni bir ipynb dosyası oluşturun.
Ctrl+Shift+P tuşlarını kullanarak Komut Paleti'ni açın.
Python: Ortam Oluştur'u arayın.
Venv.
seçeneğini belirleyin
Bir Python yorumlayıcısı seçin. 3.10 veya üzerini seçin.
Kurulumu bir dakika sürebilir. Sorunlarla karşılaşırsanız bkz . VS Code'da Python ortamları.
Paketleri yükleme ve değişkenleri ayarlama
Azure-search-documents dahil olmak üzere paketleri yükleyin.
! pip install azure-search-documents==11.6.0b1 --quiet
! pip install azure-identity --quiet
! pip install python-dotenv --quiet
Uç noktanızı ve API anahtarlarınızı sağlayın:
search_endpoint: str = "PUT-YOUR-SEARCH-SERVICE-ENDPOINT-HERE"
search_api_key: str = "PUT-YOUR-SEARCH-SERVICE-ADMIN-API-KEY-HERE"
index_name: str = "hotels-quickstart"
Dizin oluşturma
Dizin şemasını oluşturarak veya güncelleştirerek ekleyin SemanticConfiguration
. Mevcut bir dizini güncelleştiriyorsanız, belgelerinizin yapısı değişmediğinden bu değişiklik için yeniden dizin oluşturma gerekmez.
from azure.search.documents.indexes import SearchIndexClient
from azure.search.documents import SearchClient
from azure.search.documents.indexes.models import (
ComplexField,
SimpleField,
SearchFieldDataType,
SearchableField,
SearchIndex,
SemanticConfiguration,
SemanticField,
SemanticPrioritizedFields,
SemanticSearch
)
# Create a search schema
index_client = SearchIndexClient(
endpoint=search_endpoint, credential=credential)
fields = [
SimpleField(name="HotelId", type=SearchFieldDataType.String, key=True),
SearchableField(name="HotelName", type=SearchFieldDataType.String, sortable=True),
SearchableField(name="Description", type=SearchFieldDataType.String, analyzer_name="en.lucene"),
SearchableField(name="Description_fr", type=SearchFieldDataType.String, analyzer_name="fr.lucene"),
SearchableField(name="Category", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),
SearchableField(name="Tags", collection=True, type=SearchFieldDataType.String, facetable=True, filterable=True),
SimpleField(name="ParkingIncluded", type=SearchFieldDataType.Boolean, facetable=True, filterable=True, sortable=True),
SimpleField(name="LastRenovationDate", type=SearchFieldDataType.DateTimeOffset, facetable=True, filterable=True, sortable=True),
SimpleField(name="Rating", type=SearchFieldDataType.Double, facetable=True, filterable=True, sortable=True),
ComplexField(name="Address", fields=[
SearchableField(name="StreetAddress", type=SearchFieldDataType.String),
SearchableField(name="City", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),
SearchableField(name="StateProvince", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),
SearchableField(name="PostalCode", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),
SearchableField(name="Country", type=SearchFieldDataType.String, facetable=True, filterable=True, sortable=True),
])
]
semantic_config = SemanticConfiguration(
name="my-semantic-config",
prioritized_fields=SemanticPrioritizedFields(
title_field=SemanticField(field_name="HotelName"),
keywords_fields=[SemanticField(field_name="Category")],
content_fields=[SemanticField(field_name="Description")]
)
)
# Create the semantic settings with the configuration
semantic_search = SemanticSearch(configurations=[semantic_config])
scoring_profiles = []
suggester = [{'name': 'sg', 'source_fields': ['Tags', 'Address/City', 'Address/Country']}]
# Create the search index with the semantic settings
index = SearchIndex(name=index_name, fields=fields, suggesters=suggester, scoring_profiles=scoring_profiles, semantic_search=semantic_search)
result = index_client.create_or_update_index(index)
print(f' {result.name} created')
Belge yükü oluşturma
JSON belgelerini arama dizinine gönderebilirsiniz. Belgelerin dizin şemasıyla eşleşmesi gerekir.
documents = [
{
"@search.action": "upload",
"HotelId": "1",
"HotelName": "Stay-Kay City Hotel",
"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 Time's 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.",
"Description_fr": "L'hôtel est idéalement situé sur la principale artère commerciale de la ville en plein cœur de New York. A quelques minutes se trouve la place du temps et le centre historique de la ville, ainsi que d'autres lieux d'intérêt qui font de New York l'une des villes les plus attractives et cosmopolites de l'Amérique.",
"Category": "Boutique",
"Tags": [ "pool", "air conditioning", "concierge" ],
"ParkingIncluded": "false",
"LastRenovationDate": "1970-01-18T00:00:00Z",
"Rating": 3.60,
"Address": {
"StreetAddress": "677 5th Ave",
"City": "New York",
"StateProvince": "NY",
"PostalCode": "10022",
"Country": "USA"
}
},
{
"@search.action": "upload",
"HotelId": "2",
"HotelName": "Old Century Hotel",
"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.",
"Description_fr": "L'hôtel est situé dans une place du XIXe siècle, qui a été agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel moderne, fonctionnel et de première classe dans lequel l'art et les éléments historiques uniques coexistent avec le confort le plus moderne.",
"Category": "Boutique",
"Tags": [ "pool", "free wifi", "concierge" ],
"ParkingIncluded": "false",
"LastRenovationDate": "1979-02-18T00:00:00Z",
"Rating": 3.60,
"Address": {
"StreetAddress": "140 University Town Center Dr",
"City": "Sarasota",
"StateProvince": "FL",
"PostalCode": "34243",
"Country": "USA"
}
},
{
"@search.action": "upload",
"HotelId": "3",
"HotelName": "Gastronomic Landscape Hotel",
"Description": "The Hotel stands out for its gastronomic excellence under the management of William Dough, who advises on and oversees all of the Hotel's restaurant services.",
"Description_fr": "L'hôtel est situé dans une place du XIXe siècle, qui a été agrandie et rénovée aux plus hautes normes architecturales pour créer un hôtel moderne, fonctionnel et de première classe dans lequel l'art et les éléments historiques uniques coexistent avec le confort le plus moderne.",
"Category": "Resort and Spa",
"Tags": [ "air conditioning", "bar", "continental breakfast" ],
"ParkingIncluded": "true",
"LastRenovationDate": "2015-09-20T00:00:00Z",
"Rating": 4.80,
"Address": {
"StreetAddress": "3393 Peachtree Rd",
"City": "Atlanta",
"StateProvince": "GA",
"PostalCode": "30326",
"Country": "USA"
}
},
{
"@search.action": "upload",
"HotelId": "4",
"HotelName": "Sublime Palace Hotel",
"Description": "Sublime Palace Hotel is located in the heart of the historic center of Sublime in an extremely vibrant and lively area within short walking distance to the sites and landmarks of the city and is surrounded by the extraordinary beauty of churches, buildings, shops and monuments. Sublime Palace is part of a lovingly restored 1800 palace.",
"Description_fr": "Le Sublime Palace Hotel est situé au coeur du centre historique de sublime dans un quartier extrêmement animé et vivant, à courte distance de marche des sites et monuments de la ville et est entouré par l'extraordinaire beauté des églises, des bâtiments, des commerces et Monuments. Sublime Palace fait partie d'un Palace 1800 restauré avec amour.",
"Category": "Boutique",
"Tags": [ "concierge", "view", "24-hour front desk service" ],
"ParkingIncluded": "true",
"LastRenovationDate": "1960-02-06T00:00:00Z",
"Rating": 4.60,
"Address": {
"StreetAddress": "7400 San Pedro Ave",
"City": "San Antonio",
"StateProvince": "TX",
"PostalCode": "78216",
"Country": "USA"
}
}
]
Belgeleri dizine yükleme
search_client = SearchClient(endpoint=search_endpoint,
index_name=index_name,
credential=credential)
try:
result = search_client.upload_documents(documents=documents)
print("Upload of new document succeeded: {}".format(result[0].succeeded))
except Exception as ex:
print (ex.message)
index_client = SearchIndexClient(
endpoint=search_endpoint, credential=credential)
İlk sorgunuzu çalıştırma
Doğrulama adımı olarak boş bir sorguyla başlayın ve dizinin çalışır durumda olduğunu doğrulayın. Dizinde dört belge olduğunu belirten 4 sayıyla sıralanmamış bir otel adları ve açıklamaları listesi almalısınız.
# Run an empty query (returns selected fields, all documents)
results = search_client.search(query_type='simple',
search_text="*" ,
select='HotelName,Description',
include_total_count=True)
print ('Total Documents Matching Query:', results.get_count())
for result in results:
print(result["@search.score"])
print(result["HotelName"])
print(f"Description: {result['Description']}")
Metin sorgusu çalıştırma
Karşılaştırma amacıyla BM25 ilgi puanlaması ile bir metin sorgusu çalıştırın. Sorgu dizesi sağladığınızda tam metin araması çağrılır. Yanıt, daha fazla eşleşen terim örneğine veya daha önemli terimlere sahip belgelere daha yüksek puanlar verilen dereceli sonuçlardan oluşur.
Otel bünyesinde iyi bir restorana sahip olan bu sorguda, Sublime Palace Hotel'in açıklaması site içerdiğinden en üstte yer alıyor. Sık sık ortaya çıkan terimler, belgenin arama puanını yükseltir.
# Run a text query (returns a BM25-scored result set)
results = search_client.search(query_type='simple',
search_text="what hotel has a good restaurant on site" ,
select='HotelName,HotelId,Description',
include_total_count=True)
for result in results:
print(result["@search.score"])
print(result["HotelName"])
print(f"Description: {result['Description']}")
Anlamsal sorgu çalıştırma
Şimdi anlamsal derecelendirme ekleyin. Yeni parametreler ve semantic_configuration_name
değerlerini içerirquery_type
.
Aynı sorgu, ancak semantik dereceleyicinin gastronomik Landscape Hotel'i ilk sorguya göre daha ilgili bir sonuç olarak doğru şekilde tanımladığını fark edin. Bu sorgu ayrıca modeller tarafından oluşturulan açıklamalı alt yazıları döndürür. Bu örnekteki girişler ilginç açıklamalı alt yazılar oluşturamayacak kadar azdır, ancak örnek söz dizimini göstermede başarılı olur.
# Runs a semantic query (runs a BM25-ranked query and promotes the most relevant matches to the top)
results = search_client.search(query_type='semantic', semantic_configuration_name='my-semantic-config',
search_text="what hotel has a good restaurant on site",
select='HotelName,Description,Category', query_caption='extractive')
for result in results:
print(result["@search.reranker_score"])
print(result["HotelName"])
print(f"Description: {result['Description']}")
captions = result["@search.captions"]
if captions:
caption = captions[0]
if caption.highlights:
print(f"Caption: {caption.highlights}\n")
else:
print(f"Caption: {caption.text}\n")
Anlamsal yanıtlar döndür
Bu son sorguda anlamsal yanıtlar döndür.
Anlam dereceleyicisi, bir sorunun özelliklerine sahip bir sorgu dizesine yanıtlar oluşturabilir. Oluşturulan yanıt, içeriğinizden ayrıntılı olarak ayıklanır. Anlamsal bir yanıt almak için soru ve yanıtın yakından hizalanması ve modelin soruyu net bir şekilde yanıtlayan içerik bulması gerekir. Olası yanıtlar güvenilirlik eşiğini karşılayamazsa model yanıt döndürmez. Tanıtım amacıyla, bu örnekteki soru söz dizimini görebilmeniz için bir yanıt almak üzere tasarlanmıştır.
# Run a semantic query that returns semantic answers
results = search_client.search(query_type='semantic', semantic_configuration_name='my-semantic-config',
search_text="what hotel is in a historic building",
select='HotelName,Description,Category', query_caption='extractive', query_answer="extractive",)
semantic_answers = results.get_answers()
for answer in semantic_answers:
if answer.highlights:
print(f"Semantic Answer: {answer.highlights}")
else:
print(f"Semantic Answer: {answer.text}")
print(f"Semantic Answer Score: {answer.score}\n")
for result in results:
print(result["@search.reranker_score"])
print(result["HotelName"])
print(f"Description: {result['Description']}")
captions = result["@search.captions"]
if captions:
caption = captions[0]
if caption.highlights:
print(f"Caption: {caption.highlights}\n")
else:
print(f"Caption: {caption.text}\n")