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

Blog

ブログ

統合

Kentico Cloudを使用したコンテンツの検索:Algolia統合

By Martin Dobsicek  

検索は、訪問者が目的のコンテンツをすばやく見つけるのに役立つため、Webサイトの重要な部分です。 Kentico Cloudを使用すると、外部の検索エンジンを簡単に統合できるため、複雑な検索アルゴリズムを自分で実装する必要はありません。

このブログ投稿では、KenticoCloudヘッドレスCMSとAlgoliaのサンプル統合について説明します。実際、9月にKenticoCloudブログでアルゴリア検索を実装しました。

MVCアプローチを使用し、バックエンドにC#プログラミング言語を使用し、フロントエンドにJavaScriptを使用して、.NETCoreプラットフォームで機能を開発します。 KenticoCloudに保存されているコンテンツを検索します。この場合、コード例で検索するコンテンツタイプとしてブログ投稿を使用しますが、コードは任意のコンテンツタイプに合わせて簡単に変更できます。

アルゴリア入門

プロセスの最初のステップは、 Algoliaでアカウントを作成することです。登録が完了すると、ログインしてプロファイル内のAPIキーを見つけることができます。 AlgoliaのAPIを呼び出すときに使用する必要がある3つの基本的な情報があります。

  • アプリケーションID–使用するアプリケーションを識別するため
  • 検索専用APIキー–検索クエリに使用できるAPIキー(公開して表示できるため、フロントエンドで使用できます)
  • 管理APIキー–インデックスを管理するため(バックエンドでのみ使用できるように非公開にする必要があります)

また、 Algoliaのドキュメントを読んで、Algoliaの概念、API、および準備されたUIウィジェットに慣れることをお勧めします。

ここで、コードを実装するための3つの基本的な手順があります。

  • 現在のデータにインデックスを付ける
  • データが変更されたときにインデックスを作成する(Webhookを使用)
  • インデックスを検索して結果を表示します(Web訪問者がクエリを送信した場合)

現在のデータにインデックスを付ける

インデックス作成ではプライベート管理APIキーが使用されるため、データはバックエンドからインデックス作成する必要があります。 Algolia.Search NuGetパッケージを使用してAlgoliaのAPIをスムーズに操作し、 Kentico Cloud Delivery .NET SDKを使用して、KenticoCloudアプリからブログ投稿データを取得します。

まず、ブログ投稿のデータを格納するBlogPostSearchModelというモデルを用意します。モデルには、インデックスを作成するテキストを含める必要があるだけでなく、後で結果を表示する際に使用するために、他のさまざまなデータをAlgoliaインデックスに追加できます。これにより、時間を節約でき、最初にKenticoCloudアプリケーションからデータを取得する必要がなくなります。この例では、 URLSlugフィールドを追加して、ブログ投稿へのリンクを作成できるようにします。

 public class BlogPostSearchModel { public string ID { get; set; } public string UrlSlug { get; set; } public string Title { get; set; } public string Body { get; set; } public string Topic { get; set; } public string Author { get; set; }}


次に、DeliveryAPIによってContentItemタイプのオブジェクトとして返されたデータからBlogPostSearchModelオブジェクトを作成するためのメソッドを準備します。

 private static BlogPostSearchModel GetBlogPost(ContentItem item){ if (item == null) { return new BlogPostSearchModel(); } return new BlogPostSearchModel { ID = item.System.Id, UrlSlug = item.GetString('url_slug'), Title = item.GetString('title'), Body = item.GetString('body'), Topic = item.GetOptions('topic').FirstOrDefault()?.Name, Author = item.GetModularContent('author').FirstOrDefault()?.GetString('name') };}


その後、Delivery APIを使用してすべてのブログ投稿を取得するメソッドを作成し、上記のメソッドを利用してBlogPostSearchModelインスタンスのリストを作成します。 ProjectIDを使用して、ブログ投稿の取得元のプロジェクトを識別します。

 private static async Task> GetBlogPosts(){ var parameters = new List { new EqualsFilter('system.type', 'blog_post'), new OrderParameter('elements.date', SortOrder.Descending) }; DeliveryClient client = new DeliveryClient(''); var response = await client.GetItemsAsync(parameters); return response.Items.Select(GetBlogPost);}


これは、デモンストレーション目的で選択したKenticoCloudからデータを取得するための基本的なアプローチです。プロダクションコードの場合、Delivery APIを介してコンテンツを受信するための推奨される方法であるため、代わりに強く型付けされたモデルアプローチを使用することをお勧めします。

また、リッチテキストフィールドのコンテンツをサニタイズするメソッドも必要です。つまり、HTMLタグを削除し、インデックス作成中にエラーを引き起こす可能性のある特殊文字をエスケープします。

 private static string SanitizeRichText(string inputString){ // Remove HTML tags inputString = Regex.Replace(inputString, '<.*?>', string.Empty); // Decode/Escape special characters return Regex.Replace(inputString, ' ', ' ').Replace('\'', ' ').Replace('\\', '\\\\');}


今、私たちはAlgoliaのインデックスに与えられたブログの記事をインデックスするための方法を実装することができます-両方の最初のインデックス作成と将来のデータのインデックス作成に使用します。

 public static void IndexBlogPostsInAlgolia(IEnumerable blogPostsToIndex, bool isInitialIndexing){ AlgoliaClient algoliaClient = new AlgoliaClient('', ''); var objs = new List(); foreach (var blogPost in blogPostsToIndex) { objs.Add(JObject.Parse( $@'{{ ''objectID'':''{blogPost.ID}'', ''urlSlug'':''{blogPost.UrlSlug}'', ''title'':''{blogPost.Title}'', ''body'':''{SanitizeRichText(blogPost.Body)}'', ''topic'':''{blogPost.Topic}'', ''author'':''{blogPost.Author}'' }}')); } var algoliaIndex = algoliaClient.InitIndex(''); if (isInitialIndexing) { algoliaIndex.SetSettings(JObject.Parse(@'{''searchableAttributes'':[''title'', ''body'', ''topic'', ''author'']}')); } var res = algoliaIndex.AddObjects(objs);}


最後に、これらの方法を活用して、現在のブログ投稿を取得し、アルゴリアでインデックスを作成できます。

 var blogPosts = await GetBlogPosts();IndexBlogPostsInAlgolia(blogPosts, true);

データが変更されたときにインデックスを作成する

Kentico Cloudは、新しいコンテンツを公開したり、公開されたコンテンツを編集したりするたびにシステムに通知できるWebhookをサポートしています。これを有効にするには、ドキュメントの説明に従ってWebhookを設定し、Webhookからシステムへのメッセージを処理するMVCアクションメソッドを実装する必要があります。

このメソッドは、Webhook設定の「URLアドレス」フィールドで指定された特定のルートでのHttpPostリクエストのみを処理します。 (たとえば、「webhook」ルートを使用する場合、URLは「https:// ourdomain / webhook」である必要があります。)また、メッセージが途中で変更されていないことを確認する必要があります。メッセージと一緒に送信される署名には、base64でエンコードされたメッセージのハッシュが含まれています。したがって、最初に、期待される署名を計算するメソッドを準備する必要があります。

 protected string ComputeExpectedSignature(string message){ const string secret = ''; var messageBytes = Encoding.UTF8.GetBytes(message); var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(secret)); return Convert.ToBase64String(hmac.ComputeHash(messageBytes));}


次に、Webhookメッセージを処理するアクションメソッドを実装できます。

 [HttpPost][Route('webhook')]public async Task ProcessWebhookMessage([FromHeader(Name = 'X-KC-Signature')]string signature){ const string typeToProcess = 'blog_post'; if (Request.Body.CanSeek) { Request.Body.Position = 0; } var contentString = new StreamReader(Request.Body).ReadToEnd(); if (signature.Equals(ComputeExpectedSignature(contentString))) { var message = JsonConvert.DeserializeObject(contentString); var codeNames = message.Data.Items .Where(item => typeToProcess.Equals(item.Type)) .Select(item => item.Codename); if (codeNames.Any()) { try { var parameters = new List { new InFilter('system.codename', codeNames.ToArray()), new EqualsFilter('system.type', type) }; var response = await mService.WebhooksClient.GetItemsAsync(parameters); var blogPosts = response.Items.Select(GetBlogPost); IndexBlogPostsInAlgolia(blogPosts, false); } catch (AggregateException e) { // Log exception } } } return Ok();}

検索と表示結果

フロントエンド側で検索を実行して、Algoliaのサーバーに電話をかけ、サーバーにコールバックせずに直接応答を受信できるようにします。このアプローチにより、パフォーマンスが大幅に向上します。 UIの実装を容易にするために、 既存のAlgoliaウィジェットを活用することもできます。では、どのようにUIを構築するのでしょうか。

まず、ユーザーが検索クエリを入力できる入力フィールドを用意する必要があります。次に、統計(見つかった結果の数)、ページャー、(主に)検索結果などの他のUIパーツのコンテナーとして機能するいくつかのdivを追加できます。

 


結果の特定のアイテムのレイアウトは、 テンプレートによって定義されます。テンプレートは、IDが「hit-template」の


これで、適切なコンテナーに結果と追加のUI要素を表示するJavaScriptを追加できます。

まとめ

このウォークスルーでは、Kentico CloudをAlgoliaと統合して、Webサイトのコンテンツを簡単に検索できることを示しました。この機能は、ユーザーエクスペリエンスの向上に役立ちます。

アルゴリア検索を試してみませんか?

Kentico Cloudブログの検索をすでにチェックしましたか?どう思いますか?

以下のフォーラムでお知らせください。

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

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