Solrスペル・チェッカーの使用

Version:
日本語翻訳に関する免責事項

このページの翻訳はAIによって自動的に行われました。可能な限り正確な翻訳を心掛けていますが、原文と異なる表現や解釈が含まれる場合があります。正確で公式な情報については、必ず英語の原文をご参照ください。

Solrにはスペル チェッカー機能があります。この機能を使用して、他の類似した用語に基づくインライン クエリの提案をユーザーに提供できます。候補のソースは、Solrのフィールド内の用語、外部テキスト・ファイル、または他の索引内のフィールドです。

ソースは、次の4つの方法で構成できます。

  • IndexBasedSpellChecker: スペルチェックに使用される並列インデックスのソースとしてSolrインデックスを使用します。インデックス用語の基準としてフィールドを定義する必要があります。

  • DirectSolrSpellChecker: 並列インデックスを作成せずにSolrインデックスの項を使用します。

  • FileBasedSpellChecker: 外部ファイルをスペル チェック辞書として使用します。

  • WordBreakSolrSpellChecker:隣接するクエリ用語を結合したり、用語を複数の単語に分割したりします

次のベスト プラクティスをお勧めします。

  • IndexBasedSpellCheckを使用する場合は、一部のフィールド (タイトル、本文など) から、スペルチェック用に作成した別のフィールドに用語をコピーします。

  • このスペル チェッカーに対してクエリを実行するフィールドを選択するときにDirectSolrSpellCheckを使用する場合は、そのフィールドに対する分析 (特にステミング) が比較的少ないフィールドを使用します。

詳細については、Solrの資料を参照してください

Solrの構成

Solrは、以下の2つの方法で構成できます。

  • 既存の選択要求ハンドラーを使用する: すべての要求で提案を生成する必要がある場合

  • スペルチェックの提案を提供するために専用のリクエストハンドラが必要な場合は、スペルリクエストハンドラを使用します

Solrを設定するには、SolrConfig.xmlファイルを編集します。

既存の要求ハンドラーを使用する

これにより、マスターインデックスの_nameフィールドのスペルチェックが有効になります。

  1. solrconfig.xmlファイル (C:\solr-6.3.0\server\solr\configsets\sitecore_core_index\conf\solrconfig.xmlなど) を開きます。

  2. <arr name="components">ノードを見つけて有効にします。デフォルトでは無効になっています。

  3. <arr name="components">ノードに<str>spellcheck</str>を追加します。

  4. <searchComponent name="spellcheck" class="solr.SpellCheckComponent">ノードに移動します。

  5. <lst name="spellchecker">ノードの下で、<str name="field">_text_</str><str name="field">_name</str> に変更して、_nameフィールドのスペルチェックを有効にします。

動作確認するには:

  1. ブラウザでSolr Adminを開くか、コアインデックスを選択するか、次のリンクに直接アクセスしますhttp://localhost:8983/solr/#/sitecore_core_index/query

  2. spellcheckチェックボックスをオンにしてスペル チェックを有効にし、spellcheck.qテキスト フィールド ( homt ) にスペル チェック クエリを入力します

  3. Execute Query」をクリックします。

Solr Adminは、スペルチェックがSolrサーバーで機能する場合、次のようになります。

複数のSolrコアを使用する場合は、これらのコアごとにこの手順を繰り返す必要があります。

スペルリクエストハンドラの使用

これにより、マスターインデックスの_nameフィールドのスペルチェッカーが有効になります。

  1. solrconfig.xmlファイル (C:\solr-6.3.0\server\solr\configsets\sitecore_core_index\conf\solrconfig.xmlなど) を開きます。

  2. <searchComponent name="spellcheck" class="solr.SpellCheckComponent">ノードを見つけます。

  3. <lst name="spellchecker">ノードの下で、<str name="field">_text</str><str name="field">_name</str>に変更します。

  4. SolrConfig.xmlファイルを保存し、Solrを再起動します。

動作確認するには:

  1. ブラウザでhttp://localhost:8983/solr/sitecore_master_index/spell?q=_name:homy&amp;spellcheck=true&amp;spellcheck.count=10&amp;rows=100000000&amp;version=2.2&amp;spellcheck.build=true&amp;wt=json&amp;indent=trueに移動します。

うまくいけば、レスポンスは次のようになります。

オプションの設定

Solrスペル・チェッカー機能の他の多くの側面を構成することができます。これらのパラメーターは、solrconfig.xmlファイルの要求ハンドラー セクションで、ノードを<lst name="defaults">ノードに追加して構成します。

たとえば、次のスニペットでは、デフォルトのカウントとしてspellcheck.countを加算し、値を20にします。

<requestHandler name="/select" class="solr.SearchHandler">
    <!-- default values for query parameters can be specified, these
         will be overridden by parameters in the request
      -->
    <lst name="defaults">
      <str name="echoParams">explicit</str>
      <int name="rows">10</int>
      <str name="spellcheck">true</str>
     <str name="spellcheck.count">20</str>

https://cwiki.apache.org/confluence/display/solr/Spell+Checkingには詳細があります。

サンプルコード

このサンプル コードは、検索語句の結果が得られない場合に候補のリストを作成する方法を示しています。

たとえば、ユーザーが「homy」という用語を検索し、結果がない場合、homeを含むhomyに近い候補のリストを返すことができます。

Sitecoreは、使用できる2つのAPIを公開しています。

  • コードでISolrQueryの実装を使用する場合は、これを使用します。

    SolrNetProxy.Query
    public static SolrQueryResults<T> Query<T>(this IProviderSearchContext context, ISolrQuery q, QueryOptions queryOptions)
    public static SolrQueryResults<T> Query<T>(this IProviderSearchContext context, string q, QueryOptions queryOptions)
  • コードでISolrQueryを使用しない場合は、これを使用します。これは簡単な実装です。

    SolrNetProxy.GetSpellCheck
    public static SolrQueryResults<Dictionary<string, object>> GetSpellCheck(this IProviderSearchContext context, ISolrQuery q, SpellCheckHandlerQueryOptions options)

次の例は、SitecoreのSolrスペル チェッカーを使用する2つの異なる方法を示しています。

SolrNetProxy.Queryの使用

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="HighlightDemo.aspx.cs" Inherits="Sitecore.ContentSearch.SolrProvider.Example.HighlightDemo" %>
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="HighlightDemo.aspx.cs" Inherits="Sitecore.ContentSearch.SolrProvider.Example.HighlightDemo" %>
<%@ Import Namespace="Sitecore.ContentSearch.SearchTypes" %>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="Sitecore.ContentSearch" %>
<%@ Import Namespace="Sitecore.ContentSearch.SolrNetExtension" %>
<%@ Import Namespace="Sitecore.ContentSearch.SolrProvider.SolrNetIntegration" %>
<%@ Import Namespace="SolrNet.Commands.Parameters" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
     <script runat="server">
    protected void OnClick(object sender, EventArgs e)
        {
            FirstSenario();
        }
    private void FirstSenario()
        {
            var index = ContentSearchManager.GetIndex("sitecore_master_index");
            var searchText = this.txtInput.Text;
            if (string.IsNullOrEmpty(searchText))
            {
                //TODO prompt error
                this.ShowResult("Please enter a search text!");
                return;
            }
            using (var context = index.CreateSearchContext())
            {
                var results = context.Query<SearchResultItem>(string.Format("_name:{0}", searchText), new QueryOptions()
                {
                    SpellCheck = new SpellCheckingParameters()
                });
                if (results == null || results.SpellChecking == null || results.SpellChecking.Count < 1)
                {
                    this.ShowResult("No rows returned");
                    this.rptResults.DataSource = new List<string>();
                    this.rptResults.DataBind();
                    return;
                }
                var suggestions = new List<string>();
                foreach (var term in results.SpellChecking)
                {
                    foreach (var suggestion in term.Suggestions)
                    {
                        suggestions.Add(suggestion);
                    }
                }
                this.BindSuggestion(suggestions);
            }
        }
      private void ShowResult(string result)
        {
            this.divResult.InnerHtml = result;
        }
        private void BindSuggestion(List<string> suggestions)
        {
            this.rptResults.DataSource = suggestions;
            this.rptResults.DataBind();
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <h3>Spell Check Example </h3>
        <h4>Group search result by title</h4>
        <br/>
        <asp:Label runat="server" Text="Name" AssociatedControlID="txtInput"></asp:Label> &nbsp; &nbsp; 
            <asp:TextBox runat="server" ID="txtInput"></asp:TextBox> &nbsp; &nbsp; 
            <asp:Button runat="server" Text="Search" OnClick="OnClick" />
        <br/>
        <div><b>Search Results</b></div>
        <br/>
        <div id="divResult" runat="server"></div>
        <asp:Repeater id="rptResults" runat="server">
             <HeaderTemplate>
              <table cols="1" width="100%" style="padding: 5px">
          </HeaderTemplate>
            <ItemTemplate>
                <tr>
                    <td><%# Container.DataItem %></td>
                </tr>
            </ItemTemplate>
            <FooterTemplate>
                </table>
            </FooterTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>

SolrNetProxy.GetSpellCheckの使用

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SpellCheckDemo.aspx.cs" Inherits="Sitecore.ContentSearch.SolrProvider.Example.SpellCheckDemo" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
       <style>
        .resultBox {
            padding: 5px 5px 5px 5px;
            margin-bottom: 1px;
            
        }
        #divGroupFieldLists {
            border-style: dashed;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    <h3>Spell Check Example </h3>
        <h4>Group search result by title</h4>
        <br/>
        <asp:Label runat="server" Text="Name" AssociatedControlID="txtInput"></asp:Label> &nbsp; &nbsp; 
            <asp:TextBox runat="server" ID="txtInput"></asp:TextBox> &nbsp; &nbsp; 
            <asp:Button runat="server" Text="Search" OnClick="OnClick" />
        <br/>
        <div><b>Search Results</b></div>
        <br/>
        <div id="divResult" runat="server"></div>
        <asp:Repeater id="rptResults" runat="server">
             <HeaderTemplate>
              <table cols="1" width="100%" style="padding: 5px">
          </HeaderTemplate>
            <ItemTemplate>
                <tr>
                    <td><%# Container.DataItem %></td>
                </tr>
            </ItemTemplate>
            <FooterTemplate>
                </table>
            </FooterTemplate>
        </asp:Repeater>
    </div>
    </form>
</body>
</html>
SpellCheckDemo.aspx.cs
namespace Sitecore.ContentSearch.SolrProvider.Example
{
    using System;
    using System.Collections.Generic;
    using Sitecore.ContentSearch.SolrNetExtension;
    using Sitecore.ContentSearch.SolrProvider.SolrNetIntegration;
    using SolrNet.Commands.Parameters;
    using SolrNet;
    public partial class SpellCheckDemo : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }
        protected void OnClick(object sender, EventArgs e)
        {
            FirstSenario();
        }
        private void FirstSenario()
        {
            var index = ContentSearchManager.GetIndex("sitecore_master_index");
            var searchText = this.txtInput.Text;
            if (string.IsNullOrEmpty(searchText))
            {
                //TODO prompt error
                this.ShowResult("Please enter a search text!");
                return;
            }
            using (var context = index.CreateSearchContext())
            {
                var results = context.GetSpellCheck(new SolrQuery(string.Format("_name:{0}", searchText)), new SpellCheckHandlerQueryOptions()
                {
                    SpellCheck = new SpellCheckingParameters()
                    {
                        Count = 10,
                        Build = true
                    }
                });
                if (results == null || results.SpellChecking == null || results.SpellChecking.Count < 1)
                {
                    this.ShowResult("No rows returned");
                    this.rptResults.DataSource = new List<string>();
                    this.rptResults.DataBind();
                    return;
                }
                var suggestions = new List<string>();
                foreach (var term in results.SpellChecking)
                {
                    foreach (var suggestion in term.Suggestions)
                    {
                        suggestions.Add(suggestion);
                    }
                }
                this.BindSuggestion(suggestions);
            }
        }
        #region Helper Method
        private void ShowResult(string result)
        {
            this.divResult.InnerHtml = result;
        }
        private void BindSuggestion(List<string> suggestions)
        {
            this.rptResults.DataSource = suggestions;
            this.rptResults.DataBind();
        }
        #endregion
    }
}

この記事を改善するための提案がある場合は、 お知らせください!