Solrを使用して検索結果をグループ化する

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

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

メモ

このトピックはSitecore 9.0以降で有効です。

Solrには結果のグループ化機能があります。この機能を使用して、共通のフィールド値に基づいてドキュメントをグループに分類します。Solrは、各グループの上位のドキュメントを返します。

たとえば、ユーザーが「DVD」を検索すると、Solrは「TV and Video」、「Movies」、「Computers」などの3つのカテゴリを、カテゴリごとに3つの結果とともに返すことができます。この場合、クエリ用語 "DVD" は3つのカテゴリすべてに表示されます。Solrは、エンドユーザーにとってより有用なものにするために、結果をグループ化します。

この機能を使用するためにSolrで何も構成する必要はありません。

詳細については、こちらをご覧ください。

https://cwiki.apache.org/confluence/display/solr/Result+Grouping

Sitecoreとの併用

Sitecoreには、Solrの結果グループ化機能にアクセスするために使用するAPIがあります。このAPIは、既存のContentSearch APIの拡張機能として設計されています。

プロジェクトでAPIを使用するには、次の手順に従います。

  1. 次のDLLファイルをプロジェクトで参照します (Sitecore Webサイトのbinフォルダーから取得できます)。

    • SolrNet.dll

    • Sitecore.ContentSearch.dll

    • Sitecore.ContentSearch.SolrProvider.dll

    • Sitecore.ContentSearch.SolrNetExtension.dll

  2. 次の名前空間をインポートします。

    • Sitecore.ContentSearch.SolrNetExtension (SuggesterComponentの実装を含むSolrNetの拡張機能)

Result Grouping APIをISearchIndexの一部として使用できるようになりました。

  1. クエリを文字列または任意の実装として作成しますISolrQuery

  2. メソッドIProviderSearchContext.Query() 呼び出し、返された結果を型で検査します。 SolrQueryResults<T>.

返される結果には、Dictionary<string, GroupedResults<T>>であるGroupingプロパティが含まれます。ここで、Keyはグループ フィールド名、Valueはグループ化されたドキュメントの一覧 (ICollection<Group<T>>と共にグループ化された一意の一致ドキュメントの数を表すGroupedResultsのオブジェクト です 。

Group<T> オブジェクトには、Solrドキュメント、グループ値、およびグループ内のドキュメントの数が含まれます。

例えば:

APIドキュメント

Query

Solrに対してクエリを実行します。

構文

public static SolrQueryResults<T> Query<T>(
 this IProviderSearchContext context, 
 string q, 
 QueryOptions options
)

パラメーター

  • 文脈

    種類: Sitecore.ContentSearch.IProviderSearchContext

    検索プロバイダーのコンテキスト

  • q

    Solrクエリ文字列

  • オプション

    種類: SolrNet.Commands.Parameters.QueryOptions

    クエリオプション

型パラメータ

  • T

    結果アイテムのタイプ

備考

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

The following example illustrates the basic usage of result grouping.
<%@ Page Language="C#" AutoEventWireup="true" %>
<%@ Import namespace="Sitecore.ContentSearch.SolrProvider.SolrNetIntegration" %>
<%@ Import namespace="Sitecore.ContentSearch" %>
<%@ Import namespace="Sitecore.Configuration" %>
<%@ Import namespace="Sitecore.Data" %>
<%@ Import namespace="Sitecore.Data.Items" %>
<%@ Import namespace="SolrNet.Commands.Parameters" %>
<%@ Import namespace="Sitecore.ContentSearch.SearchTypes" %>
<%@ Import Namespace="Sitecore.SecurityModel" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Solr | Grouping results demo</title>
    <script runat="server">
        private void PerformSearch(object sender, EventArgs e)
        {
            using (var ctx = ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
            {
                var input = string.IsNullOrEmpty(searchTextBox.Value) ? "*" : searchTextBox.Value.Replace(" ", "+");
                string q = String.Format("(name_t:{0} OR color_t:{0}) AND _parent:110d559fdea542ea9c1c8a5df7e70ef9", input);
                var options = new QueryOptions
                                  {
                                      Grouping = new GroupingParameters
                                                     {
                                                         Fields = new [] { "type_t" },
                                                         Limit = 10
                                                     }
                                  };
                var result = ctx.Query<SitecoreUISearchResultItem>(q, options);
                StringBuilder htmlBuilder = new StringBuilder();
                foreach (var group in result.Grouping)
                {
                    foreach (var grp in group.Value.Groups)
                    {
                        htmlBuilder.Append("<div class=\"group\">");
                        htmlBuilder.AppendFormat("<div class=\"group-header\">{0}</div>", grp.GroupValue);
                        htmlBuilder.Append("<div class=\"group-item\">");
                        foreach (var item in grp.Documents)
                        {
                            htmlBuilder.AppendFormat("<span>{0} ({1})</span>", item["Name"], item["Color"]);
                        }
                        htmlBuilder.Append("</div>");
                        htmlBuilder.Append("</div>");
                    }
                }
                searchResults.InnerHtml = htmlBuilder.ToString();
            }
        }
        private void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack && Request["create"] == "true")
            {
                using (new SecurityDisabler())
                {
                    GenerateTheItems();
                }
            }
        }
        #region Create the demo items
        private void GenerateTheItems()
        {
            var master = Factory.GetDatabase("master");
            if (master.GetItem("/sitecore/templates/sample/Vehicle") != null)
            {
                return;
            }
            var sampleTemplates = master.GetItem("/sitecore/templates/sample");
            var vehicleTemplate = CreateTemplate(master, sampleTemplates);
            var home = master.GetItem("/sitecore/content/Home");
            CreateItem(home, vehicleTemplate, "Toyota", "Corolla", "Red", "Sedan");
            CreateItem(home, vehicleTemplate, "Toyota", "Avanza", "Blue", "MPV");
            CreateItem(home, vehicleTemplate, "Toyota", "Camry", "Blue", "Sedan");
            CreateItem(home, vehicleTemplate, "Honda", "Civic", "White", "Sedan");
            CreateItem(home, vehicleTemplate, "Perodua", "Myvi", "White", "Hatchback");
            CreateItem(home, vehicleTemplate, "Perodua", "Myvi", "Red", "Hatchback");
            Response.Write("Done!");
        }
        private void CreateItem(Item home, TemplateItem vehicleTemplate, string model, string name, string color, string type)
        {
            var car = home.Add(model, vehicleTemplate);
            car.Editing.BeginEdit();
            car["Color"] = color;
            car["Type"] = type;
            car["Name"] = name;
            car.Editing.EndEdit();
        }
        private TemplateItem CreateTemplate(Database master, Item parent)
        {
            var vehicleTemplate = master.Templates.CreateTemplate("Vehicle", parent);
            var dataSection = vehicleTemplate.AddSection("Data");
            dataSection.AddField("Type");
            dataSection.AddField("Color");
            dataSection.AddField("Name");
            return vehicleTemplate;
        } 
        #endregion
    </script>
    <style>
        .group {
            font-family: sans-serif;
            border: #aecce6 solid 1px;
            margin: 10px;
        }
        .group-header {
            font-size: larger;
            font-weight: bold;
            background-color: aliceblue;
            padding: 10px;
        }
        .group-item {
            padding: 10px;
            display: grid;
        }
    </style>
</head>
<body>
    <form id="form1" runat="server">
        <div align="center">
            <input type="text" id="searchTextBox" style="width: 80%;" placeholder="Enter car model or color" runat="server" autocomplete="off" />
            <asp:Button Text="Search" OnClick="PerformSearch" runat="server" />
        </div>
        <div id="searchResults" runat="server"></div>
    </form>
</body>
</html>
この記事を改善するための提案がある場合は、 お知らせください!