Sitecore Search APIを使用して日本語のアイテムを検索する方法

samatsu 12/12/2015 2745 N/A Sitecore Programming

Sitecore 7 以降 アイテムの検索を強化したSitecore Search API(サイトコアサーチAPI)が導入されました。Sitecore検索APIにより、コンテンツエディターやページエディター(エクスペリエンスエディター)からSitecore6.X時代と比べてはるかに高い精度で柔軟にアイテムを検索できるようになっています。Sitecore6.Xのレガシー検索と異なり、日本語のアイテムも、より高い精度で検索することができます。

Sitecore 検索APIはAPIなのでもちろんプログラムから使用することができます。簡単な使い方は以前こちらご紹介しました。

Sitecore Search APIを利用して気づいたかもしれませんが、日本語のアイテムをコンテンツエディターの検索タブで検索するのと同じような精度でカスタムプログラムから日本語のアイテムを検索できないことがあります。

これは多くの場合、検索時に日本語検索用のアナライザーを使用するように指定していないことが原因です。Sitecoreのクライアントインタフェースで日本語のアイテムを検索できるのはUIが日本語の場合は日本語のアナライザーを使用して検索を行っているためです。

そこで、今回は、コンテンツエディターがフリーテキスト検索で日本語アナライザーを使用するのと同じようにカスタムプログラムから言語特有のアナライザーを使用するように指定する方法をご紹介します。

早速ですが以下がサンプルプログラムです。サンプルではおまけとして特定の言語の最新のバージョンのみを検索対象とするようにしています。検索対象のルートのアイテムのIDは適当な文字列なので、実際に動作確認する場合は適切なIDに変更して試してください。

using Sitecore.ContentSearch;
using Sitecore.ContentSearch.SearchTypes;
using Sitecore.ContentSearch.Linq;

public partial class SearchForm : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        var searchRoot = new Sitecore.Data.ID("{565A8A17-032F-44AC-B506-B65F27A31241}");
        var searchRootItem = Sitecore.Context.Database.GetItem(searchRoot);
        var indexable = new SitecoreIndexableItem(searchRootItem);
        var index = ContentSearchManager.GetIndex(indexable);

        using (var context = index.CreateSearchContext())
        {
            var query = context.GetQueryable<CustomSearchResult>(new CultureExecutionContext(Sitecore.Context.Language.CultureInfo));
            var result = query.Where(x => x.Paths.Contains(searchRoot))
                                .Where(x => x.IsLatestVersion)
                                .Where(x => x.Language == Sitecore.Context.Language.Name)
                                .Where(x => x.Content == "自転車")
                                .OrderBy(x => x.CreatedDate)
                                .GetResults();
            if (result.Hits.Any())
            {
                gvSearchResult.DataSource = result.Hits.Select(x => x.Document);
                gvSearchResult.DataBind();
            }
        }
    }
}

public class CustomSearchResult : SearchResultItem
{
    [IndexField(BuiltinFields.LatestVersion)]
    public bool IsLatestVersion { get; set; }
}

ソースを見ていただくと分かるように、GetQueryable メソッドの引数に CultureExecutionContext のインスタンスを渡しているだけです。日本語のコンテンツを表示している場合は、日本語のアナライザー(Lucene.netの場合はCJKAnalyzer)が使用され、検索キーワードがトークナイズされて検索が行われます。

サンプルコードではContent(_content)と一致するインデックスデータを検索しているので検索結果の内容は、コンテンツエディターでキーワード検索した場合とほとんど同じになると思います。

CultureExecutionContext を使用してアナライザーを切り替える方法はドキュメントに書いてあるのですが気づきにくいため使い方を紹介しました。