Hızlı başlangıç: JavaScript SDK 'sını kullanarak Azure Bilişsel Arama dizini oluşturma

JavaScript 'te bir arama dizini oluşturan, yükleyen ve sorgulayan bir Node.js uygulaması oluşturmak için Azure bilişsel arama JavaScript/Typscript SDK 'sını kullanın.

Bu makalede, uygulamanın adım adım nasıl oluşturulacağı gösterilir. Alternatif olarak, kaynak kodu ve verileri indirebilir ve uygulamayı komut satırından çalıştırabilirsiniz.

Önkoşullar

Başlamadan önce, aşağıdaki araçlara ve hizmetlere sahip olursunuz:

Projenizi ayarlama

' İ, arama hizmetinizin uç noktasını ve anahtarını alarak başlatın. Ardından aşağıda özetlenen NPM ile yeni bir proje oluşturun.

Anahtar ve uç nokta kopyalama

Hizmete yapılan çağrılar, her istekte bir URL uç noktası ve erişim anahtarı gerektirir. İlk adım olarak, projenize eklenecek API anahtarını ve URL 'YI bulun. Daha sonraki bir adımda istemciyi oluştururken her iki değeri de belirtirsiniz.

  1. Azure Portal oturum açınve arama hizmetine genel bakış sayfasında URL 'yi alın. Örnek uç nokta https://mydemo.search.windows.net şeklinde görünebilir.

  2. Ayarlaranahtarlarda, hizmet üzerinde tam haklar için bir yönetici anahtarı alın, nesne oluşturuyorsanız veya silerseniz gereklidir. İki adet değiştirilebilir birincil ve ikincil anahtar vardır. Bunlardan birini kullanabilirsiniz.

    Get an HTTP endpoint and access keyHTTP uç noktası

Tüm istekler hizmetinize gönderilen her istekte bir API anahtarı gerektirir. İstek başına geçerli bir anahtara sahip olmak, isteği gönderen uygulama ve bunu işleyen hizmet arasında güven oluşturur.

Yeni NPM projesi oluşturma

VS Code ve tümleşik terminalini veya Node.js komut istemi gibi başka bir terminali açarak başlayın.

  1. Şu adı vererek bir geliştirme dizini oluşturun quickstart :

    mkdir quickstart
    cd quickstart
    
  2. Şunu çalıştırarak NPM ile boş bir proje başlatın

    npm init
    

    Lisans dışında, "MıT" olarak ayarlamanız gereken varsayılan değerleri kabul edin.

  3. @azure/search-documents@azure/search-documents'yı yükler.

    npm install @azure/search-documents
    
  4. dotenvHizmeti adı ve API anahtarımız gibi ortam değişkenlerini içeri aktarmak için kullanılan uygulamasını yükler.

    npm install dotenv
    
  5. Package. JSON dosyanızın aşağıdaki JSON 'a benzer göründüğünü denetleyerek projeleri ve bağımlılıklarını yapılandırdığınızı doğrulayın:

    {
      "name": "quickstart",
      "version": "1.0.0",
      "description": "Azure Cognitive Search Quickstart",
      "main": "index.js",
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [
        "Azure",
        "Search"
      ],
      "author": "Your Name",
      "license": "MIT",
      "dependencies": {
        "@azure/search-documents": "^11.2.0",
        "dotenv": "^8.2.0"
      }
    }
    
  6. Arama hizmeti parametrelerinizi tutmak için bir dosya . env oluşturun:

    SEARCH_API_KEY=<search-admin-key>
    SEARCH_API_ENDPOINT=https://<search-service-name>.search.windows.net
    

Değeri, <search-service-name> arama hizmetinizin adıyla değiştirin. <search-admin-key>Daha önce kaydettiğiniz anahtar değeriyle değiştirin.

index.js dosyası oluştur

Ardından, kodumuzu barındıracak ana dosya olan bir index.js dosyası oluşturacağız.

Bu dosyanın en üstünde, kitaplığı içeri aktardık @azure/search-documents :

const { SearchIndexClient, SearchClient, AzureKeyCredential, odata } = require("@azure/search-documents");

Sonra, dotenv paketin dotenv dosyasındaki parametrelerde şu şekilde okumasını gerektirmemiz gerekir:

// Load the .env file if it exists
require("dotenv").config();

// Getting endpoint and apiKey from .env file
const endpoint = process.env.SEARCH_API_ENDPOINT || "";
const apiKey = process.env.SEARCH_API_KEY || "";

İçeri aktarmalarımızın ve ortam değişkenlerinin yerine ana işlevi tanımlamaya hazırız.

SDK 'daki işlevlerin çoğu zaman uyumsuzdur, bu nedenle ana işlevimizi sunuyoruz async . Ayrıca main().catch() , karşılaşılan hataları yakalamak ve günlüğe kaydetmek için Main işlevinin altına da dahil ediyoruz:

async function main() {
    console.log(`Running Azure Cognitive Search Javascript quickstart...`);
    if (!endpoint || !apiKey) {
        console.log("Make sure to set valid values for endpoint and apiKey with proper authorization.");
        return;
    }

    // remaining quickstart code will go here
}

main().catch((err) => {
    console.error("The sample encountered an error:", err);
});

Bu şekilde, bir dizin oluşturmaya hazırız.

1-Dizin oluşturma

Hotels_quickstart_index. JSONdosyası oluşturun. Bu dosya, Azure Bilişsel Arama 'nin bir sonraki adımda yüklediğiniz belgelerle nasıl çalıştığını tanımlar. Her bir alan ile tanımlanır name ve belirtilmiş olur type . Her alan Ayrıca, Azure Bilişsel Arama alan üzerinde arama, filtreleme, sıralama ve model kullanıp kullanamayacağını belirten bir dizi dizin özniteliklerine sahiptir. Alanların çoğu basit veri türleridir, ancak bazıları AddressType dizininiz içinde zengin veri yapıları oluşturmanıza imkan tanıyan karmaşık türlerdir. Desteklenen veri türleri ve Dizin oluşturma (REST)bölümünde açıklanan dizin öznitelikleri hakkında daha fazla bilgi edinebilirsiniz.

Aşağıdakileri hotels_quickstart_index. JSON dosyasına ekleyin veya dosyayı indirin.

{
    "name": "hotels-quickstart",
    "fields": [
        {
            "name": "HotelId",
            "type": "Edm.String",
            "key": true,
            "filterable": true
        },
        {
            "name": "HotelName",
            "type": "Edm.String",
            "searchable": true,
            "filterable": false,
            "sortable": true,
            "facetable": false
        },
        {
            "name": "Description",
            "type": "Edm.String",
            "searchable": true,
            "filterable": false,
            "sortable": false,
            "facetable": false,
            "analyzerName": "en.lucene"
        },
        {
            "name": "Description_fr",
            "type": "Edm.String",
            "searchable": true,
            "filterable": false,
            "sortable": false,
            "facetable": false,
            "analyzerName": "fr.lucene"
        },
        {
            "name": "Category",
            "type": "Edm.String",
            "searchable": true,
            "filterable": true,
            "sortable": true,
            "facetable": true
        },
        {
            "name": "Tags",
            "type": "Collection(Edm.String)",
            "searchable": true,
            "filterable": true,
            "sortable": false,
            "facetable": true
        },
        {
            "name": "ParkingIncluded",
            "type": "Edm.Boolean",
            "filterable": true,
            "sortable": true,
            "facetable": true
        },
        {
            "name": "LastRenovationDate",
            "type": "Edm.DateTimeOffset",
            "filterable": true,
            "sortable": true,
            "facetable": true
        },
        {
            "name": "Rating",
            "type": "Edm.Double",
            "filterable": true,
            "sortable": true,
            "facetable": true
        },
        {
            "name": "Address",
            "type": "Edm.ComplexType",
            "fields": [
                {
                    "name": "StreetAddress",
                    "type": "Edm.String",
                    "filterable": false,
                    "sortable": false,
                    "facetable": false,
                    "searchable": true
                },
                {
                    "name": "City",
                    "type": "Edm.String",
                    "searchable": true,
                    "filterable": true,
                    "sortable": true,
                    "facetable": true
                },
                {
                    "name": "StateProvince",
                    "type": "Edm.String",
                    "searchable": true,
                    "filterable": true,
                    "sortable": true,
                    "facetable": true
                },
                {
                    "name": "PostalCode",
                    "type": "Edm.String",
                    "searchable": true,
                    "filterable": true,
                    "sortable": true,
                    "facetable": true
                },
                {
                    "name": "Country",
                    "type": "Edm.String",
                    "searchable": true,
                    "filterable": true,
                    "sortable": true,
                    "facetable": true
                }
            ]
        }
    ],
    "suggesters": [
        {
            "name": "sg",
            "searchMode": "analyzingInfixMatching",
            "sourceFields": [
                "HotelName"
            ]
        }
    ]
}

Dizin tanımımız ile, ana işlevin Dizin tanımına erişebilmesi için index.jshotels_quickstart_index. JSON ' ı içeri aktarmak istiyoruz.

const indexDefinition = require('./hotels_quickstart_index.json');

Ana işlevin içinde, SearchIndexClient Azure bilişsel arama için dizin oluşturmak ve yönetmek üzere kullanılan bir oluşturur.

const indexClient = new SearchIndexClient(endpoint, new AzureKeyCredential(apiKey));

Daha sonra, zaten varsa dizini silmek istiyoruz. Bu, test/tanıtım kodu için yaygın bir uygulamadır.

Bunu, dizini silmeye çalışan basit bir işlev tanımlayarak yapacağız.

async function deleteIndexIfExists(indexClient, indexName) {
    try {
        await indexClient.deleteIndex(indexName);
        console.log('Deleting index...');
    } catch {
        console.log('Index does not exist yet.');
    }
}

İşlevi çalıştırmak için Dizin tanımından dizin adını ayıklayıp indexName ile birlikte indexClient işlevine geçirin deleteIndexIfExists() .

const indexName = indexDefinition["name"];

console.log('Checking if index exists...');
await deleteIndexIfExists(indexClient, indexName);

Bundan sonra, yöntemi ile dizini oluşturmaya hazırız createIndex() .

console.log('Creating index...');
let index = await indexClient.createIndex(indexDefinition);

console.log(`Index named ${index.name} has been created.`);

Örneği çalıştırma

Bu noktada, örneği çalıştırmaya hazırsınız demektir. Aşağıdaki komutu çalıştırmak için bir Terminal penceresi kullanın:

node index.js

Kaynak kodu indirdiyseniz ve gerekli paketleri henüz yüklemediyseniz, önce çalıştırın.

Program tarafından gerçekleştirilen eylemleri açıklayan bir ileti serisi görmeniz gerekir.

Azure portal arama hizmetinize Genel Bakış ' ı açın. Dizinler sekmesini seçin. Aşağıdakine benzer bir şey görmeniz gerekir:

Azure portal, arama hizmetine genel bakış, dizinler sekmesinin ekran görüntüsü

Sonraki adımda, dizine veri ekleyeceksiniz.

2-belge yükleme

Azure Bilişsel Arama 'de belgeler, sorguların dizin oluşturma ve çıkışlara yönelik giriş olan veri yapılarıdır. Bu tür verileri dizine gönderebilir veya bir Dizin Oluşturucukullanabilirsiniz. Bu durumda, belgeleri dizine iteceğiz program aracılığıyla.

Belge girişleri bir veritabanındaki satırlar, blob depolamada Bloblar veya bu örnekte olduğu gibi, diskteki JSON belgeleri olabilir. Oteller. JSON dosyasını indirebilir ya da aşağıdaki içerikle kendi oteller. JSON dosyanızı oluşturabilirsiniz:

{
    "value": [
        {
            "HotelId": "1",
            "HotelName": "Secret Point Motel",
            "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.6,
            "Address": {
                "StreetAddress": "677 5th Ave",
                "City": "New York",
                "StateProvince": "NY",
                "PostalCode": "10022"
            }
        },
        {
            "HotelId": "2",
            "HotelName": "Twin Dome Motel",
            "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.6,
            "Address": {
                "StreetAddress": "140 University Town Center Dr",
                "City": "Sarasota",
                "StateProvince": "FL",
                "PostalCode": "34243"
            }
        },
        {
            "HotelId": "3",
            "HotelName": "Triple 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.8,
            "Address": {
                "StreetAddress": "3393 Peachtree Rd",
                "City": "Atlanta",
                "StateProvince": "GA",
                "PostalCode": "30326"
            }
        },
        {
            "HotelId": "4",
            "HotelName": "Sublime Cliff Hotel",
            "Description": "Sublime Cliff 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 Cliff is part of a lovingly restored 1800 palace.",
            "Description_fr": "Le sublime Cliff 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 Cliff 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.6,
            "Address": {
                "StreetAddress": "7400 San Pedro Ave",
                "City": "San Antonio",
                "StateProvince": "TX",
                "PostalCode": "78216"
            }
        }
    ]
}

Indexdefinition ile yaptığımız gibi, hotels.json verilere ana işlevimizde erişilebilmesi için hotels.json en üstünde içeri aktarmanız gerekir.

const hotelData = require('./hotels.json');

Arama dizinine veri dizini oluşturmak için şimdi bir oluşturmanız gerekiyor SearchClient . SearchIndexClientBir dizin oluşturmak ve yönetmek için kullanıldığında, SearchClient belgeleri karşıya yüklemek ve dizini sorgulamak için kullanılır.

Oluşturmak için iki yol vardır SearchClient . İlk seçenek sıfırdan bir oluşturmak için SearchClient :

 const searchClient = new SearchClient(endpoint, indexName, new AzureKeyCredential(apiKey));

Alternatif olarak, öğesini getSearchClient()SearchIndexClient oluşturmak için yöntemini kullanabilirsiniz SearchClient :

const searchClient = indexClient.getSearchClient(indexName);

Artık istemci tanımlandığından, belgeleri arama dizinine yükleyin. Bu durumda, mergeOrUploadDocuments() aynı anahtara sahip bir belge zaten varsa, belgeleri karşıya yükleyecek veya mevcut bir belgeyle birleştirilecek olan yöntemini kullanırız.

console.log('Uploading documents...');
let indexDocumentsResult = await searchClient.mergeOrUploadDocuments(hotelData['value']);

console.log(`Index operations succeeded: ${JSON.stringify(indexDocumentsResult.results[0].succeeded)}`);

Programını ile yeniden çalıştırın node index.js . Adım 1 ' de gördüğenlerden biraz farklı bir ileti kümesi görmeniz gerekir. Bu kez , Dizin mevcut olur ve uygulama yeni dizin oluşturmadan ve verileri kendisine göndermeksizin silme hakkında bir ileti görmeniz gerekir.

Sonraki adımda sorguları çalıştırmadan önce, programın bir saniye beklemesi için bir işlev tanımlayın. Bu işlem, dizin oluşturmanın tamamlandığından emin olmak için yalnızca test/demo amaçları için yapılır ve sorgularımızda, belgelerin dizinde kullanılabilmesini sağlar.

function sleep(ms) {
    var d = new Date();
    var d2 = null;
    do {
        d2 = new Date();
    } while (d2 - d < ms);
}

Programın bir saniye beklemesi için sleep aşağıdaki gibi işlevi çağırın:

sleep(1000);

3 - Dizin arama

Bir dizin oluşturulduktan ve belgeler karşıya yüklendiktan sonra dizine sorgu göndermeye hazır oluruz. Bu bölümde, size farklı sorgu işlevselliği parçalarını göstermek için arama dizinine beş farklı sorgu gönderebilirsiniz.

Sorgular, main sendQueries() işlevinde çağırarak şu şekilde çağırdiğimiz bir işlevde yazılır:

await sendQueries(searchClient);

Sorgular yöntemi search() kullanılarak searchClient gönderilir. İlk parametre arama metni, ikinci parametre ise ek arama seçenekleridir.

İlk sorgu, her şeyi aramaya eşdeğer olan öğesini * arar ve dizinde üç alanı seçer. Gereksiz verilerin geri çekilerek sorgularınıza gecikme süresi eklenebilecek olduğundan, yalnızca ihtiyacınız olan alanlar için select en iyi uygulamadır.

Bu searchOptions sorgu için ayrıca olarak includeTotalCounttrue ayarlanmıştır. Bu ayar, bulunan eşleşen sonuç sayısını geri verir.

async function sendQueries(searchClient) {
    console.log('Query #1 - search everything:');
    let searchOptions = {
        includeTotalCount: true,
        select: ["HotelId", "HotelName", "Rating"]
    };

    let searchResults = await searchClient.search("*", searchOptions);
    for await (const result of searchResults.results) {
        console.log(`${JSON.stringify(result.document)}`);
    }
    console.log(`Result count: ${searchResults.count}`);

    // remaining queries go here
}

Aşağıda özetlenen diğer sorgular da işleve sendQueries() eklenmiştir. Okunabilirlik için burada ayrılmıştır.

Bir sonraki sorguda arama terimini belirtir ve yalnızca durum ile eşit olan sonuçların "wifi" geri dönmesi için bir filtre de içeririz. 'FL' Sonuçlar ayrıca otel tarafından Rating sıralandı.

console.log('Query #2 - Search with filter, orderBy, and select:');
let state = 'FL';
searchOptions = {
    filter: odata`Address/StateProvince eq ${state}`,
    orderBy: ["Rating desc"],
    select: ["HotelId", "HotelName", "Rating"]
};

searchResults = await searchClient.search("wifi", searchOptions);
for await (const result of searchResults.results) {
    console.log(`${JSON.stringify(result.document)}`);
}

Ardından, parametresi kullanılarak arama tek bir aranabilir alanla searchFields sınırlıdır. Bu, yalnızca belirli alanlardaki eşleşmelerle ilgilendiğinizi biliyorsanız sorguyu daha verimli hale getirir.

console.log('Query #3 - Limit searchFields:');
searchOptions = {
    select: ["HotelId", "HotelName", "Rating"],
    searchFields: ["HotelName"]
};

searchResults = await searchClient.search("sublime cliff", searchOptions);
for await (const result of searchResults.results) {
    console.log(`${JSON.stringify(result.document)}`);
}
console.log();

Bir sorguya dahil etmek için bir diğer yaygın seçenek de facets seçeneğidir. Facets, kullanıcıların hangi değerleri filtreleyene kadar filtreleye ekleyebilirsiniz?

console.log('Query #4 - Use facets:');
searchOptions = {
    facets: ["Category"],
    select: ["HotelId", "HotelName", "Rating"],
    searchFields: ["HotelName"]
};

searchResults = await searchClient.search("*", searchOptions);
for await (const result of searchResults.results) {
    console.log(`${JSON.stringify(result.document)}`);
}

Son sorgu, getDocument() yöntemini searchClient kullanır. Bu, bir belgeyi anahtarıyla verimli bir şekilde alasınız.

console.log('Query #5 - Lookup document:');
let documentResult = await searchClient.getDocument(key='3')
console.log(`HotelId: ${documentResult.HotelId}; HotelName: ${documentResult.HotelName}`)

Örneği çalıştırma

Programı ile node index.js çalıştırın. Şimdi, önceki adımlara ek olarak sorgular gönderilir ve sonuçlar konsola yazılır.

Kaynakları temizleme

Kendi aboneliğinizde çalışırken, projenin sonunda oluşturduğunuz kaynaklara hala ihtiyacınız olup olmadığını belirlemek iyi bir fikirdir. Çalışır durumda bırakılan kaynaklar maliyetlerin artmasına neden olabilir. Kaynakları teker teker silebilir veya tüm kaynak grubunu silerek kaynak kümesinin tamamını kaldırabilirsiniz.

Sol gezinti bölmesindeki Tüm kaynaklar veya Kaynak grupları bağlantısını kullanarak portalda kaynakları bulabilir ve yönetebilirsiniz.

Ücretsiz bir hizmet kullanıyorsanız üç dizin, dizin ve veri kaynağıyla sınırlı olduğunu unutmayın. Sınırın altında kalmak için portalda tek tek öğeleri silebilirsiniz.

Sonraki adımlar

Bu JavaScript hızlı başlangıçta dizin oluşturmak, belgelerle yüklemek ve sorgu çalıştırmak için bir dizi görev üzerinde çalıştısınız. Öğrenmeye devam etmek için aşağıdaki öğreticiyi ve örneği önericileri (ileri tür veya otomatik tamamlama sorguları), filtreleri ve çok yönlü gezintiyi denemek için bir springboard olarak deneyin.