---
title: "Solrの自動提案の使用"
slug: "using-solr-auto-suggest"
abstract: "Solrの提案機能を使って、クエリ用語の自動提案を提供します"
---
# Solrの自動提案の使用

> !注このトピックはSitecore 9.0以降にも適用されます。

SolrにはSuggestComponentという「提案」コンポーネントがあります。このコンポーネントを使ってユーザーにクエリ用語の自動提案を提供します。例えば、オートコンプリート機能付きのテキストボックスを作成し、ユーザーがテキストボックス内でクエリ用語を入力すると提案された用語が表示されます。

また、Solrスペルチェック機能を使って自動提案を実装することもできます。専用のSuggesterComponentはLuceneの提案ツール実装を使用し、Luceneで利用可能なすべてのルックアップ実装をサポートしています。スペルチェック機能を使うことで、結果の他の側面も設定できます。

詳細はこちらをご覧ください:

[https://wiki.apache.org/solr/Suggester](https://wiki.apache.org/solr/Suggester)

[https://cwiki.apache.org/confluence/display/solr/Suggester](https://cwiki.apache.org/confluence/display/solr/Suggester)

## ルックアップ実装

solrConfig.xmlファイルのlookupImplパラメータを使って、提案インデックス内の用語を調べる際に使うルックアップアルゴリズムを指定します。いくつかの実装から選択できます。これらはすべてLookupクラスのサブクラスであり、追加パラメータの設定が必要なものもあります:

-   JaspellLookupジャスペルに基づく木構造表現です。
-   TSTLookup:即時のデータ構造更新が可能な三元木ベースの表現です。
-   FSTLookup:オートマトンベースの表現です。構築は遅いものの、実行時のメモリ消費ははるかに少なくなります。
-   WFSTLookup:重み付きオートマトン表現;より細かい順位付けのための FSTLookup の代替手段です。

## 辞書の実装

solrConfig.xmlファイルのdictionaryImplパラメータを使って、suggestインデックスに用語を格納する辞書実装を指定します。複数の実装から選択できます。これらはすべてDictionaryFactoryクラスのサブクラスです:

-   DocumentDictionaryFactory: 用語、重み、そしてインデックスから取られた任意のペイロードを含む辞書です。
-   DocumentExpressionDictionaryFactory: は DocumentDictionaryFactoryと同じ辞書実装ですが、ユーザーは weightExpression タグで任意の式を指定できます。
-   HighFrequencyDictionaryFactory: この辞書実装により、非常に一般的な用語が他の用語を圧倒してしまう場合に、頻度の低い項を切り落とす閾値を追加できます。
-   FileDictionaryFactoryこの辞書実装では、推奨エントリを含む外部ファイルを使用できます。重みやペイロードも利用できます。

> !注1つのSuggesterComponent内に複数の辞書を持つことができます。リクエスト時に、どの辞書を使うかを指定する必要があります。

## Solrでの自動提案の設定

オートアサバイゼントを使用するには、SuggesterComponentとリクエストハンドラを追加・設定する必要があります。

### SuggesterComponentの追加と設定

SuggesterComponent検索コンポーネントは複数の設定パラメータを受け入れます。ルックアップ実装の選択(lookupImpl)と辞書実装の選択(dictionaryImpl)が、必要なパラメータの一部を決定します。

以下のサンプルは、指定した検索や辞書実装に関わらず使用できる一般的なパラメータを示しています:

<searchComponent name="suggest" class="solr.SuggestComponent">
 <lst name="suggester">
 <str name="name">mySuggester</str>
 <str name="lookupImpl">FSTLookupFactory</str>
 <str name="dictionaryImpl">DocumentDictionaryFactory</str>
 <str name="field">myFieldName</str>
 <str name="suggestAnalyzerFieldType">string</str>
 <str name="buildOnStartup">false</str>
 </lst>
</searchComponent>

#### SuggesterComponentパラメータ

パラメータ

概要

searchコンポーネント名

検索コンポーネントの任意の名称です。

名称

この提案者に対する象徴的な名前です。

lookupImpl

ルックアップ実装。指定されていない場合、デフォルトのルックアップ実装は JaspellLookupFactoryです。

辞書インプル

使用する辞書実装。指定がない場合、sourceLocationが使われない限り、デフォルトの辞書実装はHighFrequencyDictionaryFactoryされます。この場合、辞書実装はFileDictionaryFactoryとなります。

フィールド

インデックスのフィールドを提案項の基礎として使います。 sourceLocation が空の場合は、このインデックスフィールドの項が使用されます。  
  
このフィールドは、提案の基礎として使うために保存されなければなりません。 [copyFieldルールを使って](https://cwiki.apache.org/confluence/display/solr/Copying+Fields) 、ドキュメント内の他のフィールドの用語から成る特別な「提案」フィールドを作成できます。  
  
フィールドは最小限の解析量しか含めていないので、スキーマ内で基本的なトークナイザーやフィルターだけを使うフィールドタイプを作成することもできます。

出典 所在地

FileDictionaryFactoryを使う場合は辞書ファイルへのパスです。この値が空の場合は、メインインデックスが項と重みのソースとして使われます。

storeDir

辞書ファイルが保存されているフォルダです。

buildOnCommit または buildOnOptimize

trueの場合、ソフトコミット後にルックアップデータ構造が再構築されます。false(デフォルト)の場合、ルックアップデータ構造はURLパラメータsuggest.build=trueからの要求でのみ構築されます。  
  
ソフトコミットごとに辞書を再構築するために buildOnCommit を使うか、インデックスが最適化された場合にのみ辞書を構築する buildOnOptimize 。  
  
一部のルックアップ実装は、特に大きなインデックスの場合、構築に時間がかかることがあります。このような状況では、 buildOnCommit や buildOnOptimize、特に softCommitsの頻度が高い場合は推奨されません。代わりに、 suggest.build=trueを使ったリクエストを手動で発行して、より低い頻度で提案ツールを構築することをお勧めします。

buildOnStartup

trueの場合、Solr開始またはコアの再ロード時にルックアップデータ構造が構築されます。  
  
このパラメータを指定しない場合、 SuggesterComponent はルックアップデータ構造がディスク上にあるかを確認し、見つからなければビルドします。  
  
これを true に設定すると、提案データ構造を構築する必要があるため、コアが読み込み(または再読み込み)に長引く可能性があります。これにはかなり時間がかかることがあります。通常はこの設定を false に設定し、 suggest.build=trueで手動でリクエストを発行する提案器を構築するのが望ましいです。  
  
この設定が trueされると、コアの読み込みと再読み込みに時間がかかることがあります。これは、提案データ構造が起動時に再構築されるためです。したがって、 falseに設定し、 suggest.build=trueで手動で提案器を構築することをお勧めします。

### リクエストハンドラ

solrconfig.xmlファイルを編集し、リクエストハンドラを追加する必要があります。このリクエストハンドラは他のリクエストハンドラと同じように動作します。提案リクエストのデフォルトパラメータを設定するために使います。リクエストハンドラの定義にはSuggesterComponentを組み込む必要があります:

<requestHandler name="/suggest" class="solr.SearchHandler" startup="lazy">
 <lst name="defaults">
 <str name="suggest">true</str>
 <str name="suggest.count">10</str>
 </lst>
 <arr name="components">
 <str>suggest</str>
 </arr>
</requestHandler>

#### リクエストハンドラパラメータ

これらのパラメータを指定してリクエストハンドラのデフォルト設定が可能です。

パラメータ

概要

提案

このパラメータは常に trueでなければなりません。これは、このハンドラに提出されたクエリに対して常に SuggesterComponent を実行したいからです。

suggest.dictionary

検索コンポーネントで設定された辞書コンポーネントの名前を指定します。このパラメータは必須です。リクエストハンドラで設定するか、クエリ時にパラメータとして送信できます。

suggest.Q

提案検索に使用するクエリを指定します。

提案。カウント

ソルが返す提案の数を指定します。

suggest.cfq

Solrがコンテキストフィールドに基づいて提案をフィルタリングするために使用するコンテキストフィルタークエリを指定します(提案者がサポートする場合)。

提案。ビルド

trueの場合、Solrは提案者インデックスを作成します。これはおそらく初期リクエストにのみ有用です。特に本番環境では、すべてのリクエストに対して辞書を構築するのは望ましくありません。  
  
検索コンポーネントの buildOnCommit または buildOnOptimize パラメータを使って索引を更新し続けてください。

提案。再装填

trueの場合、Solrは提案者インデックスをリロードします。

提案。ビルドオール

trueの場合、Solrはすべての提案者インデックスを作成します。

suggest.reloadAll

trueの場合、Solrはすべての提案者インデックスを再読み込みします。

## Sitecoreでの利用

SitecoreにはSolrの提案機能にアクセスするためのAPIがあります。このAPIは既存のContentSearch APIの拡張として設計されています。

プロジェクトでAPIを使用するには以下の手順に従ってください:

1.  以下のDLLファイルをプロジェクトに参照してください。Sitecoreウェブサイトの bin フォルダから取得できます:
    -   SolrNet.dll
    -   Sitecore。ContentSearch.dll
    -   Sitecore。ContentSearch.SolrProvider.dll
    -   Sitecore。ContentSearch.SolrNetExtension.dll
2.  以下のネームスペースをインポートします:
    -   Sitecore。ContentSearch.SolrNetExtension(SuggesterComponentの実装を含むSolrNetの拡張機能)
    -   Sitecore。ContentSearch.SolrProvider.SolrNetIntegration(ISearchIndexを拡張するメソッドを含む)

これでSuggest APIをISearchIndexの一部として利用できます:

1.  型のクエリオブジェクトを作成する SolrSuggestQuery
2.  IProviderSearchContext.Suggest()メソッドを呼び出し、返された結果の型を確認しますSolrSuggestHandlerQueryResults.

返される結果は、Keyが提案に使われる辞書名、Valueが提案リストとともに見つかった用語の数を表すSuggestResultオブジェクトDictionary<string, SuggestResult>です(IEnumerable<Suggestion>)。

各Suggestionオブジェクトには、推奨された項、ウェイト、ペイロードが含まれています。

例えば:

![Using\_Solr\_auto-suggest-Picture\_1-rId14-2080622872.png](https://doc.sitecore.com/api/markdown-image/xp/ja/developers/103/platform-administration-and-architecture/images/Using_Solr_auto-suggest-Picture_1-rId14-2080622872.png)

## APIドキュメント

Suggest(SolrSuggestQuery, SuggestHandlerQueryOptions)

提供されたクエリに合致する用語を提案します。

### 構文論

public static SolrSuggestHandlerQueryResults Suggest(
 this IProviderSearchContext context,
 SolrSuggestQuery q,
 SuggestHandlerQueryOptions options
)

### パラメータ

-   背景
    
    タイプ: Sitecore.ContentSearch.IProviderSearchContext
    
    検索プロバイダーの文脈
    
-   q
    
    タイプ: Sitecore.ContentSearch.SolrNetExtension.SolrSuggestQuery
    
    クエリオブジェクト
    
-   オプション
    
    タイプ: Sitecore.ContentSearch.SolrNetExtension.SuggestHandlerQueryOptions
    
    クエリオプション
    

### 発言

このメソッドは、定義されたオプション集合(2番目のパラメータ)でSolrに対してクエリ(最初の引数)を実行し、結果を値の辞書として取得します。

## 例

以下の例は基本的な用法を示しています:

<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Import Namespace="System.Web.Services" %>
<%@ Import Namespace="Sitecore.ContentSearch.SolrProvider.SolrNetIntegration" %>
<%@ Import Namespace="Sitecore.ContentSearch" %>
<%@ Import Namespace="Sitecore.ContentSearch.SolrNetExtension" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
 <title>Suggester demo</title>
 <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
 <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script>
 <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js" integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU=" crossorigin="anonymous"></script>
 <script runat="server">
 WebMethod
 public static IEnumerable<string> GetSuggestion(string term)
 {
 using (var ctx = ContentSearchManager.GetIndex("sitecore\_master\_index").CreateSearchContext())
 {
 SolrSuggestQuery q = term;
 var options = new SuggestHandlerQueryOptions
 {
 Parameters = new SuggestParamaters
 {
 Count = 3,
 Build = true
 }
 };
 var result = ctx.Suggest(q, options);
 return result.Suggestions"mySuggester".Suggestions.Select(a => a.Term);
 }
 }
 </script>
</head>
<body>
 <form id="form1" runat="server">
 <div class="ui-widget" align="center">
 <input type="text" id="searchTextBox" style="width: 80%;" placeholder="Enter your item name" />
 </div>
 <script type="text/javascript">
 $("#searchTextBox").autocomplete({
 source: function (request, response) {
 var param = { term: $('#searchTextBox').val() };
 $.ajax({
 url: "SuggestDemo.aspx/GetSuggestion",
 data: JSON.stringify(param),
 dataType: "json",
 type: "POST",
 contentType: "application/json; charset=utf-8",
 dataFilter: function (data) { return data; },
 success: function (data) {
 response($.map(data.d,
 function (item) {
 return {
 value: item
 }
 }));
 },
 error: function (XMLHttpRequest, textStatus, errorThrown) {
 alert(textStatus);
 }
 });
 },
 minLength: 2
 });
 </script>
 </form>
</body>
</html>