当サイトを最適な状態で閲覧していただくにはブラウザのJavaScriptを有効にしてご利用下さい。
JavaScriptを無効のままご覧いただいた場合には一部機能がご利用頂けない場合や正しい情報を取得できない場合がございます。
承知しました
本サイトではWebサイトのエクスペリエンスを向上させるために、Cookieを使用しています。Cookieはブラウザの設定から無効にできます。本サイトで使用するCookieについては、プライバシーポリシーをご確認ください。

Blog

ブログ

統合

Azure CognitiveSearchをKenticoKontentと統合する方法

By Christopher Jennings  

訪問者はあなたのコンテンツを探しています。彼らが探しているものを正確に見つけるのをどのように助けることができますか?

1つの答えは、検索を追加することです。より一般的なものの1つであるAzureCognitiveSearchを統合する方法を見てみましょう。この記事では、インデックスの作成、更新、クエリの基本について説明します。インデックスには、DancingGoatサンプルプロジェクトの記事が含まれます。

Azure CognitiveSearch入門

開始するには、最初に使用するAzure CognitiveSearchサービスをプロビジョニングする必要があります。これは、 Azureポータルで実行できます。 Microsoftには、無料で開始するために使用できる無料の階層があります。サービスをプロビジョニングした後、サービス名と管理APIキーをメモする必要があります。以下のスクリーンショットは、Azureポータルの管理キーの場所を示しています。

AzurePortalでAzureCognitive SearchServiceの管理者キーを見つける場所のスクリーンショット
AzurePortalでAzureCognitive SearchServiceの管理者キーを見つける場所のスクリーンショット

初期インデックスの作成

プロジェクトのスピンアップ

始める前に、 完全なソースはGitHubで入手できます。それをダウンロードして、フォローするか、プロジェクトを新しく作成することができます。

この簡単なデモを作成するには、新しいASP.NET CoreWebアプリケーションを作成することから始めます。このチュートリアルのコードサンプルは、名前に「Kontent-Azure-Search-Demo」を使用することを前提としています。以下に示すように、「Webアプリケーション(Model-View-Controller)」テンプレートを選択します。

Kentico Kontent

次に、いくつかの設定値を追加する必要があります。 appsettings.json追加できます。一部の値は機密性が高いため、代わりに「ユーザーシークレット」の使用を検討することをお勧めします。

Kentico Kontent

いずれの場合も、これらのJSONファイルのいずれかにいくつかのキーと値のペアを追加する必要があります。値に基づいて更新する必要があります。 SearchServiceNameは、Azure Cognitive SearchServiceの名前です。 SearchServiceAdminApiKeyは、前述の管理者キーです。 SearchServiceIndexNameは、インデックスに使用する名前です。他の2つはKenticoKontent用です。 KenticoProjectIDは、検索しているプロジェクトのプロジェクトIDです。将来作成するコードは、DancingGoatサンプルプロジェクトを想定しています。 KontentWebhookSecretは、後で使用するものです。今のところ、これは空白にするか、ダミー値のままにしておくことができます。

 { 'SearchServiceName': 'your-azure-search-service-name', 'SearchServiceAdminApiKey': 'YourAdminApiKey', 'SearchIndexName': 'desired-index-name', 'KontentProjectID': 'kontent-project-id', 'KontentWebhookSecret': 'WebhookSecretValue'}

次に、NuGetパッケージをいくつか追加する必要があります。 Kentico.Kontent.DeliveryパッケージとMicrosoft.Azure.Searchパッケージの両方を見つけて追加します。これらにより、KontentSDKとAzureCognitive SearchSDKがプロジェクトに追加されます。

モデルの追加

Keyは、Azure検索が各インデックス付きアイテムを識別するために使用するプロパティを識別します。これは、 System.ComponentModel.DataAnnotations名前空間にあります。

IsSearchableは、ユーザーが検索できるようにするデータがプロパティに含まれているかどうかを示します。これは、 Microsoft.Azure.Search名前空間にあります。

IsRetrievableは、特定のプロパティが検索結果で返されるかどうかを示します。これは、Microsoft.Azure.Search名前空間にあります。これはデフォルトでtrueに設定されているため、検索結果(記事の本文など)でプロパティを返したくない場合にのみ追加する必要があります。

Analyzer(AnalyzerName.AsString.EnMicrosoft)は、使用するアナライザーをAzureに指示します。これは、Microsoft.Azure.Search.Models名前空間にあります。 EnMicrosoftアナライザーは、デフォルトのアナライザーよりも英語の単語をよく理解します。その結果、より良い検索結果を提供できます。

デモでは、「Models」フォルダー内のArticle.csファイルに次のコードを追加できます。

 using Microsoft.Azure.Search;using Microsoft.Azure.Search.Models;using System;using System.ComponentModel.DataAnnotations;namespace Kontent_Azure_Search_Demo.Models{ public class Article { [IsSearchable] [Analyzer(AnalyzerName.AsString.EnMicrosoft), IsRetrievable(false)] public string Body { get; set; } [Key] public string ID { get; set; } public DateTime? PostDate { get; set; } [IsSearchable] [Analyzer(AnalyzerName.AsString.EnMicrosoft)] public string Summary { get; set; } [IsSearchable] [Analyzer(AnalyzerName.AsString.EnMicrosoft)] public string Title { get; set; } public string UrlPattern { get; set; } }}

ロジックの構築

次に、主要な操作を処理するためのヘルパーをいくつか作成しましょう。 Kontentから記事を取り出し、Azureで検索インデックスを管理し、検索を実行する必要があります。

Kontentヘルパー

まず、プロジェクトルートに「Helpers」フォルダを作成しましょう。 KontentHelper.csという新しいクラスファイルを作成します。このヘルパークラスには、Kontentから記事を取得するために必要なメソッドがあります。この新しいファイルに、以下を追加します。

 using Kentico.Kontent.Delivery;using Kontent_Azure_Search_Demo.Models;using Microsoft.Extensions.Configuration;using System.Collections.Generic;using System.Linq;using System.Threading.Tasks;namespace Kontent_Azure_Search_Demo.Helpers{ public class KontentHelper { private readonly IDeliveryClient deliveryClient; public KontentHelper(IConfiguration configuration) { var projectId = configuration['KontentProjectID']; this.deliveryClient = DeliveryClientBuilder.WithProjectId(projectId).Build(); } public async Task GetArticleByUrlPattern(string urlPattern) { var parameters = new List { new EqualsFilter('system.type', 'article'), new EqualsFilter('elements.url_pattern', urlPattern), new LimitParameter(1) }; var response = await deliveryClient.GetItemsAsync(parameters); return response.Items.FirstOrDefault(); } public async Task> GetArticlesForSearch() { var parameters = new List { new EqualsFilter('system.type', 'article'), new OrderParameter('elements.post_date', SortOrder.Descending) }; var response = await deliveryClient.GetItemsAsync(parameters); return response.Items.Select(GetArticle); } public async Task> GetArticlesForSearch(IEnumerable ids) { var parameters = new List { new EqualsFilter('system.type', 'article'), new InFilter('system.id', string.Join(',',ids)), new LimitParameter(1) }; var response = await deliveryClient.GetItemsAsync(parameters); return response.Items.Select(GetArticle); } private Article GetArticle(ContentItem item) { if (item == null) { return new Article(); } return new Article { Body = item.GetString('body_copy'), ID = item.System.Id, PostDate = item.GetDateTime('post_date'), Summary = item.GetString('summary'), Title = item.GetString('title'), UrlPattern = item.GetString('url_pattern'), }; } }}

コンストラクターはアプリケーション構成を受け入れ、それを使用して配信クライアントを作成します。メソッドは、この配信クライアントを使用してKontentから記事を取得します。

GetArticleByUrlPatternメソッドは、渡されたURLパターンに一致する最初の記事を取得します。詳細ページです。

GetArticlesForSearchメソッドは、配信APIからすべての記事を取得します。そのオーバーロードは、提供されたIDと一致するIDを持つすべての記事を取得します。どちらの場合も、取得した結果を記事クラスに変換します。

GetArticleメソッドは、記事のコンテンツアイテムを記事クラスにマップします。 GetArticlesForSearchメソッドとそのオーバーロードによって使用されるプライベートメソッドです。

検索ヘルパー

次に、「Helpers」フォルダにSearchHelper.csという新しいクラスファイルを作成します。このヘルパークラスには、Azureで検索インデックスを管理し、クエリを実行するために必要なメソッドが含まれます。この新しいファイルに、以下を追加します。

using Microsoft.Azure.Search;using Microsoft.Azure.Search.Models;using Microsoft.Extensions.Configuration;using System.Collections.Generic;using System.Linq;using Index = Microsoft.Azure.Search.Models.Index;namespace Kontent_Azure_Search_Demo.Helpers{ public class SearchHelper { private readonly string indexName; private readonly ISearchIndexClient searchIndexClient; private readonly SearchServiceClient searchServiceClient; public SearchHelper(IConfiguration configuration) { indexName = configuration['SearchIndexName']; searchServiceClient = CreateSearchServiceClient(configuration); searchIndexClient = searchServiceClient.Indexes.GetClient(indexName); } public void AddToIndex(IEnumerable documents) { var actions = documents.Select(a => IndexAction.Upload(a)); var batch = IndexBatch.New(actions); searchIndexClient.Documents.Index(batch); } public void CreateIndex() { var definition = new Index() { Name = indexName, Fields = FieldBuilder.BuildForType() }; searchServiceClient.Indexes.Create(definition); } public void DeleteIndexIfExists() { if (searchServiceClient.Indexes.Exists(indexName)) { searchServiceClient.Indexes.Delete(indexName); } } public IEnumerable QueryIndex(string searchText) { var parameters = new SearchParameters(); var results = searchIndexClient.Documents.Search(searchText, parameters); return results.Results.Select(r=>r.Document); } public void RemoveFromIndex(IEnumerable documents) { var actions = documents.Select(a => IndexAction.Delete(a)); var batch = IndexBatch.New(actions); searchIndexClient.Documents.Index(batch); } private SearchServiceClient CreateSearchServiceClient(IConfiguration configuration) { string searchServiceName = configuration['SearchServiceName']; string adminApiKey = configuration['SearchServiceAdminApiKey']; return new SearchServiceClient(searchServiceName, new SearchCredentials(adminApiKey)); } }}

コンストラクターは、いくつかの再利用可能なリソースを準備します。インデックス名を保存し、検索サービスクライアントを作成し、検索インデックスクライアントのコピーを保存します。

AddToIndexメソッドは、AzureSearchインデックスへの記事の追加を処理します。ドキュメントを取得し、それらのアップロードアクションのバッチを作成し、それをAzureに送信して処理します。 Articleクラスのような装飾されたドキュメントクラスが必要です。

CreateIndexメソッドは、渡されたクラスに基づいてインデックス定義を作成します。 Articleクラスのような装飾されたクラスを期待しています。次に、Azureでインデックスを作成します。

DeleteIndexIfExistsメソッドは、構成されたインデックスがAzureに既に存在するかどうかを判断します。存在する場合は削除します。それ以外の場合は、何もしません。

QueryIndexメソッドは、検索テキストを想定しています。このテキストをAzureに渡して、検索を実行し、結果を返します。結果からドキュメントのリストのみを返します。

RemoveFromIndexメソッドは、Azureインデックスからのドキュメントの削除を処理します。ドキュメントを取得し、それらの削除アクションのバッチを作成して、処理のためにAzureに送信します。ドキュメントは、機能するドキュメントキーとして機能するプロパティを提供するだけで済みます。 Articleクラスのような装飾されたドキュメントクラスが必要です。

プライベートCreateSearchServiceClientメソッドはコンストラクター用です。 Azure CognitiveSearchの検索サービスクライアントの作成を処理します。構成された検索サービス名と管理APIキーを読み取ります。次に、AzureのSDKを使用して検索サービスクライアントを作成します。

基本的なUIの作成

検索コントローラーとビュー

次に、検索操作を管理するコントローラーを追加する必要があります。 SearchControllerという名前の新しい空のMVCコントローラーを追加することから始めます。次に、以下を追加します。

using Kontent_Azure_Search_Demo.Helpers;using Kontent_Azure_Search_Demo.Models;using Microsoft.AspNetCore.Mvc;using Microsoft.Extensions.Configuration;using System.IO;using System.Linq;using System.Threading.Tasks;namespace Kontent_Azure_Search_Demo.Controllers{ public class SearchController : Controller { private readonly KontentHelper kontentHelper; private readonly SearchHelper searchHelper; public SearchController(IConfiguration configuration) { kontentHelper = new KontentHelper(configuration); searchHelper = new SearchHelper(configuration); } public IActionResult Create() { searchHelper.DeleteIndexIfExists(); searchHelper.CreateIndex
(); ViewData['Message'] = 'Index deleted/created.'; return View('Index'); } public IActionResult Index(string searchText) { if (string.IsNullOrWhiteSpace(searchText)) { return View(); } var results = searchHelper.QueryIndex
(searchText); return View(results); } public IActionResult Initialize() { var articles = kontentHelper.GetArticlesForSearch().Result; searchHelper.AddToIndex
(articles); ViewData['Message'] = 'Index initialized.'; return View('Index'); } }}

コンストラクターは、依存性注入を使用して構成値を公開します。 SearchHelperクラスのインスタンスを初期化して、コントローラーアクションで使用できるようにします。

最初のアクションであるCreateは、使用しているインデックスを作成(または再作成)することです。呼び出されると、これはSearchHelperクラスのdeleteおよびcreate検索インデックスメソッドを呼び出します。これにより、インデックスが完全にクリーンな状態で開始されていることが確認されます。また、ページを更新できるようViewData簡単なステータスメッセージを書き込みます。最後に、コードがすべての検索アクションに対して単一のビューを共有するため、インデックスビューを返します。

2番目のメソッドIndexは、検索コントローラーの基本的なインデックスビューを返します。

最後のメソッドであるInitialize 、Kontentからすべての記事を取得し、それらをインデックスに追加します。その主な目的は、初期データをインデックスにロードすることです。

次に、コントローラーのビューを作成しましょう。 「検索」という名前の新しいフォルダーを「ビュー」フォルダーに作成し、そこに次のようIndex.cshtml

 @model IEnumerable
@{ ViewData['Title'] = 'Search Page';}

Index actions

Create index Initialize index
@ViewData['Message']
@{ if (Model != null) {

@Model.Count() Results

foreach (var document in Model) {

@document.Title

@document.Summary

} }}

これにより、作成アクションと初期化アクションのボタンとシンプルな検索ボックスを備えたシンプルなページが表示されます。結果ページとしても機能します。返された結果には、タイトル、リンクされた記事の詳細ページ、および概要が表示されます。コントローラとビューをまだ追加していないため、詳細リンクはまだ機能しません。今それをしましょう。

記事の管理者と表示

リンク先の結果ビューを提供するために、記事の最低限の詳細ビューを追加しましょう。 「Controllers」フォルダーに戻り、新しい空のMVCコントローラーを追加します。この1つのArticle名前を付け、次を追加します。

using Kontent_Azure_Search_Demo.Helpers;using Microsoft.AspNetCore.Mvc;using Microsoft.Extensions.Configuration;using System.Threading.Tasks;namespace Kontent_Azure_Search_Demo.Controllers{ public class ArticleController : Controller { private readonly KontentHelper kontentHelper; public ArticleController(IConfiguration configuration) { kontentHelper = new KontentHelper(configuration); } [Route('article/{urlPattern}')] public async Task Detail(string urlPattern) { var item = await kontentHelper.GetArticleByUrlPattern(urlPattern); return View(item); } }}

コンストラクターは構成を受け入れ、初期化されたKontentヘルパーを保存します。

Detailメソッドは、渡されたURLパターンを取得し、そのコンテンツアイテムを取得して、ビューに渡します。このビューを作成しましょう。

「Views」フォルダに「Article」という新しいフォルダを作成します。以下を使用して、そこにDetail.cshtmlファイルを追加します。

 @model Kentico.Kontent.Delivery.ContentItem@{ ViewData['Title'] = Model.GetString('title');}@if (Model.GetAssets('teaser_image').Count() > 0){ var image = Model.GetAssets('teaser_image').First(); @image.Description}

@Model.GetString('title')

@Html.Raw(Model.GetString('body_copy'))

これにより、渡されたコンテンツアイテムが取得され、ティーザー画像(存在する場合)、タイトル、および本文のコピーが表示されます。これは簡単な例にすぎないため、あまり処理しません。たとえば、リッチテキストフィールド内のアイテムリンク、コンポーネント、またはアイテムは解決されません。

試してみる

それはたくさんのコードでしたが、今では試してみるのに必要なものがすべて揃っています。 F5か、プロジェクトのデバッグを開始して、ブラウザーでプロジェクトを起動できます。ウェルカムページが読み込まれたら、 /searchを追加して、作成した検索ページにアクセスします。次のようになります。

Kentico Kontent

最初に行う必要があるのは、「インデックスの作成」ボタンをクリックしてインデックスを作成することです。ページがリロードされ、「インデックスが削除/作成されました」と表示されます。メッセージ。次に、「インデックスの初期化」ボタンをクリックして、インデックスをロードします。ダンシングゴートからインデックスに記事をロードした後、ページがリロードされます。リロード後、「インデックスが初期化されました」と表示されます。メッセージ。最後に、実際の検索を試す準備ができました。 「コーヒー」を検索すると、次のようなものが表示されます。

Kentico Kontent

結果の1つをクリックすると、次のような詳細ページが表示されます。

Kentico Kontent

インデックスを最新の状態に保つ

すばらしいので、機能します。どのように更新しておくのですか? Kontentを使用すると、Kontentプロジェクトの特定のイベントに反応するようにWebhookを構成できます。

ローカルコードのパブリックURLを取得する

まず、ローカルマシンでKontentからWebhookを受信するように設定しましょう。これをまだ処理する方法がない場合は、簡単で無料のオプションとしてngrokを使用する方法について説明します。開始するには、指示に従ってください。起動する準備ができたら、以下のコマンドを実行して、ローカル開発サーバーをポイントします。プロジェクトが実行されている場所にlocalhost:44345を更新する必要があります。

 ./ngrok http https://localhost:44345 -host-header='localhost:44345'

そのコマンドを実行すると、次のようなメッセージが表示されます。

Kentico Kontent

Kontent Webhookのターゲットとして、リストの最後にあるURLの1つを使用することをお勧めします。上のスクリーンショットでは、「https://a241e689.ngrok.io」を使用します。

KenticoKontentでのWebhookの構成

次に、KontentでWebhookを構成しましょう。 「設定」に移動し、「Webhook」を選択します。 「CreateNewWebhook」ボタンをクリックして、Webhook名を入力します。次に、エンドポイントへのパブリックURLを入力し、その末尾に「/ webhook」を追加してください。 「公開」および「非公開」配信APIトリガーを必ず有効にしてください。また、残りのトリガーをクリアします。次のようになります。

Kentico Kontent

コードでのWebhookのサポート

アプリケーションの設定

まず、appsettings.json(またはユーザーsecrets.json )にappsettings.jsonする必要があります。上記のWebhook設定画面からシークレットをコピーします。 KontentWebhookSecret設定値に貼り付けます。

モデルとWebhookヘルパー

KontentWebhookModels.csという新しいファイルを追加します。その中に、以下を追加します。

 using Newtonsoft.Json;using System;namespace Kontent_Azure_Search_Demo.KontentWebhookModels{ public class Data { [JsonProperty('items')] public Item[] Items { get; set; } [JsonProperty('taxonomies')] public Taxonomy[] Taxonomies { get; set; } } public class Item { [JsonProperty('codename')] public string Codename { get; set; } [JsonProperty('id')] public string Id { get; set; } [JsonProperty('language')] public string Language { get; set; } [JsonProperty('type')] public string Type { get; set; } } public class Message { [JsonProperty('api_name')] public string ApiName { get; set; } [JsonProperty('id')] public Guid Id { get; set; } [JsonProperty('operation')] public string Operation { get; set; } [JsonProperty('project_id')] public Guid ProjectId { get; set; } [JsonProperty('type')] public string Type { get; set; } } public class Taxonomy { [JsonProperty('codename')] public string Codename { get; set; } [JsonProperty('id')] public string Id { get; set; } } public class Webhook { [JsonProperty('data')] public Data Data { get; set; } [JsonProperty('message')] public Message Message { get; set; } }}

これは、KontentがWebhookで送信するJSONに一致するモデルのコレクションです。

KontentWebhookHelper.csという名前の「Helpers」フォルダーに新しいヘルパークラスを追加しましょう。これには次のものが含まれます。

using Kontent_Azure_Search_Demo.KontentWebhookModels;using Microsoft.Extensions.Configuration;using Newtonsoft.Json;using System;using System.Collections.Generic;using System.Linq;using System.Security.Cryptography;using System.Text;namespace Kontent_Azure_Search_Demo.Helpers{ public class KontentWebhookHelper { private readonly string webhookSecret; public KontentWebhookHelper(IConfiguration configuration) { webhookSecret = configuration['KontentWebhookSecret']; } public ValidationResult ValidateAndProcessWebhook(string signature, string body) { var hash = GenerateHash(body, webhookSecret); if (signature != hash) { return new ValidationResult { IsValid = false, ErrorMessage = 'Invalid signature' }; } // Manually deserialize request body because we needed to use the raw value previously to validate the request var webhook = JsonConvert.DeserializeObject(body); var isContentItemVariantEvent = webhook.Message.Type == 'content_item_variant'; if (!isContentItemVariantEvent) { return new ValidationResult { IsValid = false, ErrorMessage = 'Not content item variant event' }; } var isPublishevent = webhook.Message.Operation == 'publish'; var isUnpublishEvent = webhook.Message.Operation == 'unpublish'; if (!isPublishevent && !isUnpublishEvent) { return new ValidationResult { IsValid = false, ErrorMessage = 'Not publish/unpublish event' }; } var articles = webhook.Data.Items.Where(i => i.Type == 'article' && i.Language == 'en-US'); if (articles.Count() == 0) { return new ValidationResult { IsValid = false, ErrorMessage = 'No 'en-US' articles effected by this event' }; } return new ValidationResult { IsValid = true, Articles = articles }; } private string GenerateHash(string message, string secret) { secret ??= ''; UTF8Encoding SafeUTF8 = new UTF8Encoding(encoderShouldEmitUTF8Identifier: false, throwOnInvalidBytes: true); byte[] keyBytes = SafeUTF8.GetBytes(secret); byte[] messageBytes = SafeUTF8.GetBytes(message); using HMACSHA256 hmacsha256 = new HMACSHA256(keyBytes); byte[] hashmessage = hmacsha256.ComputeHash(messageBytes); return Convert.ToBase64String(hashmessage); } } public class ValidationResult { public IEnumerable Articles { get; set; } public string ErrorMessage { get; set; } public bool IsValid { get; set; } public string Operation { get; set; } }}

コンストラクターはアプリケーション設定を受け入れ、Webhookシークレットを保存します。

ValidateAndProcessWebhookメソッドは、x-kc-signatureヘッダーと完全なWebhook本体を受け取ります。リクエストがKontentからのものであることを検証します。次に、検索インデックスに対して実行可能な何かがあることを確認します。いくつかのことをチェックして、実行可能なものがあるかどうかを判断します。まず、コンテンツアイテムのバリアントに対してWebhookが起動したことを確認します。次に、操作が公開イベントまたは非公開イベントのいずれかであったことを確認します。最終チェックでは、イベントのアイテムのいずれかがen-US言語の記事であるかどうかを判断します。これらのチェックのいずれかが失敗した場合、メソッドはエラーメッセージとともに誤った検証結果を返します。チェックに合格すると、真の検証結果がWebhookに含まれる記事を返します。

GenerateHash メソッドは、ドキュメントに記載されているハッシュアルゴリズムを実装します。

検索コントローラーの更新

検索コントローラーに切り替えて、Kontentに追加した「/ webhook」URLに応答するアクションを追加する必要があります。

namespace Kontent_Azure_Search_Demo.Controllers{ public class SearchController : Controller { // ...other private fields... private readonly SearchHelper searchHelper; public SearchController(IConfiguration configuration) { // ...other constructor code... kontentWebhookHelper = new KontentWebhookHelper(configuration); } // ...other controller actions... [HttpPost('webhook')] public async Task ProcessWebhook() { // Manually read request body so we can use it to validate the request. Body is gone if we use [FromBody] on a parameter. string bodyRaw; using (var reader = new StreamReader(Request.Body)) { bodyRaw = await reader.ReadToEndAsync(); } var processedWebhook = kontentWebhookHelper.ValidateAndProcessWebhook(Request.Headers['X-KC-Signature'], bodyRaw); if (!processedWebhook.IsValid) { return processedWebhook.ErrorMessage; } if (processedWebhook.Operation == 'publish') { var articlesToUpdate = kontentHelper.GetArticlesForSearch(processedWebhook.Articles.Select(a => a.Id)).Result; searchHelper.AddToIndex(articlesToUpdate); } if (processedWebhook.Operation == 'unpublish') { var articlesToRemove = processedWebhook.Articles.Select(a => new Article { ID = a.Id }); searchHelper.RemoveFromIndex(articlesToRemove); } return 'Updated index'; } }}

KontentWebhookHelperの新しいプライベートフィールドを追加しました。コンストラクターが初期化します。また、新しいコントローラーアクションを追加しました。

新しいProcessWebhookアクションは、「/ webhook」URLへのHTTP投稿に応答します。署名の検証に未加工の本体を使用する必要があるため、本体を手動で解析します。

Webhookの本体と署名をValidateAndProcessWebhookメソッドに渡します。結果が有効でない場合は、メソッドから渡されたエラーメッセージを返します。有効な場合は、「公開」操作か「非公開」操作かに基づいてアイテムを更新または削除します。

公開操作の場合は、 GetArticlesForSearchヘルパーのGetArticlesForSearchメソッドを呼び出します。 Webhookから記事のIDを渡して、新しいデータを取得します。アイテムデータを取得すると、検索ヘルパーのAddToIndexメソッドを呼び出してインデックスを更新します。

非公開操作の場合、 ArticleクラスのIEnumerableを作成します。 Webhookで送信された記事のIDのみを使用してこのリストを作成します。最後に、検索ヘルパーのAddToIndexメソッドを呼び出して、インデックスを更新します。

Kontent Webhookに応答し、インデックスを最新の状態に保つために必要なのはこれだけです。

ソースコードと次のステップ

このデモでは、すべての基本を見てきました。 Kontentのコンテンツを使用して、Azure検索インデックスを初期化、検索、および更新しました。上記のすべてを1つのパッケージで確認したい場合は、ソースをGitHubで入手できます

これは、Azure検索の包括的な実装とはほど遠いものです。ファセットや並べ替えなど、ここでは触れていない機能がたくさんあります。また、1つの言語で1つのコンテンツタイプのみを取り上げました。もう少し探しているのであれば、これらのいずれかを実装することは、次の素晴らしいステップになります。

Headless CMSの導入をお考えでしょうか?

クラウドとマルチデバイスに最適化されたKentico Kontentをお試しください