SharePoint 2013 検索のためのサーバー オブジェクト モデルについて

こんにちは SharePoint サポートの森 健吾 (kenmori) です。今回の投稿では、SharePoint 2010 からのアップグレード シナリオにおいて、SharePoint 2013 でサーバー オブジェクト モデル (以下 SSOM) を使用して検索する方法をご紹介します。

まず、今回の投稿は、アップグレード シナリオを想定している開発者の方には、問題となる可能性がありますため早めに情報を提供する動きに至りました。

開発者に適切に情報を伝える目的を優先しますので、本投稿の難易度としては SharePoint における検索設定の基礎知識、および検索オブジェクト モデルを使用したソリューションを一通り使用した簡単なシステムを開発できるレベル (初級から中級程度) の開発者を想定した内容となります。

そのため、この内容を最低限理解するために必要とする、検索アーキテクチャ等の基礎知識や、キーワード検索、プロパティ検索、検索範囲、検索インデックス、管理プロパティ等の説明は、このページに書ききれなくなることが想定されますため割愛します。リファレンスは記載しますので、必要な場合はご参照いただくことでご了承ください。

タイトル : エンタープライズ検索の管理 (SharePoint Server 2010)
アドレス : https://technet.microsoft.com/ja-jp/library/ee792877(v=office.14).aspx

タイトル :SharePoint Server 2013 で検索を計画する
アドレス : https://technet.microsoft.com/ja-jp/library/cc263400.aspx

SharePoint 2010 の検索 SSOM について

SharePoint 2010 の検索 SSOM には、以下の 2 つのクラスを使用していました。それぞれ、異なる構文で検索を実行することが特徴です。

FullTextSqlQuery ・・・ SQL 構文を使用して検索条件を指定
  SELECT Title, CONTENTCLASS, SITE, Path FROM SCOPE() Where "scope" ='All Sites' AND CONTAINS('"test * "') ORDER BY "Title" DESC

KeywordQuery   ・・・ キーワード クエリ構文を使用して検索条件を指定
  test author:Shakesp* IsDocument:1

タイトル : 検索クエリを作成する
アドレス : https://msdn.microsoft.com/ja-jp/library/ee556426(v=office.14).aspx

SQL 構文とキーワード クエリ構文の違いについては、本コンテンツでもご紹介いたしますが、あらかじめ上記サイトからもご確認ください。

 

SharePoint 2013 の検索 SSOM について

SharePoint 2013 では、Fast for SharePoint 2010 を踏襲した大規模な検索アーキテクチャの変更が実施されました。その結果、下位互換性を保てなくなった機能が一部削除されています。

その一つに検索 SSOM として存在していた FullTextSqlQuery クラスが存在します。FullTextSqlQuery クラスを使用した検索ソリューションを SharePoint 2013 上に展開した場合、以下のような例外がスローされます。

 System.NotSupportedException: 指定されたメソッドはサポートされていません。
 場所 Microsoft.Office.Server.Search.Query.FullTextSqlQuery.PreQueryExecute()
 場所 Microsoft.Office.Server.Search.Query.Query.ExecuteQuery() 
 場所 Microsoft.Office.Server.Search.Query.SearchExecutor.ExecuteQueryInternal(Query
 query) 
 場所 Microsoft.Office.Server.Search.Query.SearchExecutor.ExecuteQuery(Query query)

これは、SharePoint Foundation 検索ライブラリ (Microsoft.SharePoint.Search.Query) を使用しても同様です。つまり、SharePoint 2013 では FullTextSqlQuery の定義は存在するものの、NotSupportedException が生成されるのみの実装です。つまり、今バージョンより KeywordQuery クラスを使用した実装に移行する必要があります。

なお、FullTextSqlQuery クラスの定義は以後のバージョンで削除される予定です。

 

FullTextSqlQuery クラスから KeywordQuery クラスを使用する際の移行について

SharePoint 2013 で引き続き検索 SSOM を使用する場合は、KeywordQuery クラスを使用したソリューションへの移行を検討する必要があることをご説明させていただきました。今回の投稿は、そのポイントとなる箇所をメインにご説明いたします。

概要

1. 表示列として管理プロパティを指定する方法について
2. 検索範囲 (検索先) の指定について
3. フルテキスト・非フルテキスト述語の指定について
4. 管理プロパティを使用した並べ替えについて

まず、上記 4 つの項目でご説明するにあたり、サンプル コードを以下に記載し、FullTextSqlQuery クラスと KeywordQuery クラスの検索処理を実装するためのコードを比較します。

 

SharePoint 2010 の FullTextSqlQuery サンプル

移行シナリオを想定してまず SharePoint 2010 における FullTextSqlQuery を使用したコードの例を以下に記載します。

  SearchServiceApplicationProxy proxy = (SearchServiceApplicationProxy)SearchServiceApplicationProxy.GetProxy(SPServiceContext.GetContext(site));
 FullTextSqlQuery ftsq = new FullTextSqlQuery(proxy);
 ftsq.ResultsProvider = SearchProvider.Default;
 ftsq.ResultTypes = ResultType.RelevantResults;
 ftsq.QueryText = "SELECT Title, CONTENTCLASS, SITE, Path FROM SCOPE() Where  "scope" ='All Sites' AND CONTAINS('"test * "') ORDER BY  "Title" DESC";
 ResultTableCollection resultTables = ftsq.Execute();
 ResultTable relevantResults = resultTables[ResultType.RelevantResults];
 DataTable resultDataTable = new DataTable();
 resultDataTable.Load(relevantResults, LoadOption.OverwriteChanges);
 dataGridView1.DataSource = resultDataTable;

QueryText プロパティに指定する検索文字列には SQL 構文を指定します。

タイトル : SharePoint 検索の SQL 構文のリファレンス
アドレス : https://msdn.microsoft.com/ja-jp/library/ee558869(v=office.14).aspx

上記のサイトに記載されている通り、様々なステートメントをサポートしていますので、柔軟な検索が実施できている状況となります。

・SELECT ・・・ 表示列を簡単に選択できます。
・FROM  ・・・ SharePoint 2007 以降は SCOPE() のみです。
・WHERE ・・・ 検索範囲、検索キーワード、プロパティ検索で使用します。
・ORDER BY・・・ 主に管理プロパティを使用した並べ替えを行います。

また、特に WHERE 句が実現できる範囲については、より詳細に確認が必要となります。

タイトル : SharePoint 検索の SQL 構文の WHERE 句
アドレス : https://msdn.microsoft.com/ja-jp/library/ms544086(v=office.14).aspx

なお、検索において実際に絞り込みを行う際に、重要とされる WHERE 句についてです。上述の通り検索範囲、自由形式のクエリ、プロパティ検索で使用しますが、以下のようにさらに細かく処理が分類できます。

フルテキスト述語  ・・・ CONTAINS 述語(* 接頭辞一致)、FREETEXT 述語
非フルテキスト述語 ・・・ LIKE, =, <, >, <=, >=, <> など

(補足)
フルテキスト述語は検索インデックスを使用して高速な検索を実行できます。非フルテキスト述語は、メタデータ ストアに対して T-SQL を実行することで値を絞り込む処理です。
キーワード クエリ構文の検索では構文が全く異なることから、これらの設定を引き続き使用するための代替案を確認する必要があると認識しています。

 

SharePoint 2013 の KeywordQuery サンプル

次に SharePoint 2013 における KeywordQuery を使用したコードの例を以下に記載します。

  SearchServiceApplicationProxy ssap = (SearchServiceApplicationProxy)SearchServiceApplicationProxy.GetProxy(SPServiceContext.GetContext(mySite));
 Microsoft.Office.Server.Search.Query.KeywordQuery myQuery = new Microsoft.Office.Server.Search.Query.KeywordQuery(ssap);
 myQuery.QueryInfo.AdvancedSearch = true;
 myQuery.QueryText = "???"; // 後述にていくつか例を記載します。
 myQuery.SelectProperties.Add("Title");
 myQuery.SelectProperties.Add("Path");
 myQuery.SelectProperties.Add("ContentTypeId");
 myQuery.SortList.Add("Rank", SortDirection.Descending);
 SearchExecutor mySearchEx = new SearchExecutor();
 ResultTableCollection myResultCol = mySearchEx.ExecuteQuery(myQuery);
 ResultTable myResultTable = myResultCol.Filter("TableType", KnownTableTypes.RelevantResults).Single(relevantTable => relevantTable.QueryRuleId == Guid.Empty);
 DataTable myDataTable = new DataTable();
 myDataTable.Load(myResultTable, LoadOption.OverwriteChanges);
 dataGridView1.DataSource = myDataTable;

では、実際にサンプル コードを眺めながら、ソリューションのアップグレード方法について検討していきましょう。

 

1. 表示列として管理プロパティを指定する方法について

SQL 構文において、SELECT ステートメントに含めていた表示列の指定については、KeywordQuery.SelectProperties に管理プロパティの名前を指定して表示列を追加することで対処が可能です。

 myQuery.SelectProperties.Add("Title");
myQuery.SelectProperties.Add("Path");
myQuery.SelectProperties.Add("ContentTypeId");

タイトル : KeywordQuery.SelectProperties property
アドレス : https://msdn.microsoft.com/en-us/library/microsoft.office.server.search.query.keywordquery.selectproperties(v=office.15).aspx

ただし、管理プロパティが検索結果として "取得可能" であるかどうかについては、管理プロパティの設定を確認しておく必要があります。
この点につきましては、以下の Technet をご参考にしてください。

タイトル : SharePoint Server 2013 の検索スキーマの概要
アドレス : https://technet.microsoft.com/ja-jp/library/jj219669(office.15).aspx#MP_Overview
参考箇所 : 管理プロパティの設定の概要

2017.1.5 追記
表示列として HitHighlightedSummary を使用する場合、HitHighlightedProperties 列で表示対象とする管理プロパティを指定する必要があります。

 myQuery.HitHighlightedProperties.Add("Title");
myQuery.HitHighlightedProperties.Add("Url");

2. 検索範囲 (検索先) の指定について

SQL 構文で Where 句で指定していた検索範囲の指定については、QueryText プロパティで scope プロパティの絞り込みを実施することで指定が可能です。

  myQuery.QueryText = "scope:\"All Sites\"";

補足

SharePoint 2013 からは、検索範囲は下位互換のために残されており、新しいバージョンからは検索先を使用することなります。
検索先を指定する方法は KeywordQuery.SourceId プロパティに GUID 型で値を指定し、絞り込む必要があります。

  SourceRecord source = searchProxy.GetResultSourceByName("カスタム検索先", new SearchObjectOwner(SearchObjectLevel.SPSite, mySite.RootWeb));
 myQuery.SourceId = source.Id;

タイトル : 検索の新機能 (SharePoint Server 2013)
アドレス : https://technet.microsoft.com/ja-jp/library/ee667266.aspx#itpro_WhatsNewEntSrch_RelevanceNew
参考箇所 : 検索先

 

3. フルテキスト・非フルテキスト述語の指定について

SQL 構文で Where 句で指定していたフルテキストおよび非フルテキスト述語の指定については、一部の条件を除き移行が可能です。
キーワード クエリ構文は、KQL (Keyword Query Language) と呼ばれるようになりました。

本項目については、以下のリファレンスを参照しながら説明していきます。

タイトル : キーワード クエリ構文のリファレンス
アドレス : https://msdn.microsoft.com/ja-jp/library/ee558911.aspx

 

なお、後記にて記載する KQL は、QueryText プロパティに指定したものとご認識ください。ソース コードの部分は割愛します。

自由形式のクエリ

QueryText プロパティにスペース区切りで自由形式に文字列を指定した場合は、フルテキスト インデックスに格納された用語との完全一致に基づいて、結果が返されます。

federated search

ワイルドカード演算子 (*) を使用して先頭一致を有効にすることにより、CONTAINS 述語で実現できていた接頭辞一致も引き続き可能です。

search fed*

(補足)
接尾辞一致のフルテキスト検索ははじめから存在していません。

 

プロパティ制限検索

プロパティ検索については、以下の構文で実現が可能です。

<プロパティ名><演算子><プロパティ値>

特によく使用される演算子は : (コロン) であり、以下のような検索キーワードをよく見かけると思います。

author:Shakesp*

これらは、KQL においてプロパティを制限する構文であり、上記の例は Author プロパティが Shakesp で始まる値をフルテキスト インデックスに格納されているプロパティから検索する動作です。

なお、演算子を変更することで、非フルテキスト検索も実行可能です。しかし、注意点があります。上述のサイトに記載されている通り、プロパティ制限の有効なプロパティ演算子は以下の通りです。

:, =, <, >, <=, >=, <>, ..

上記でお気づきかもしれませんが、KQL では非フルテキスト述語であるLIKE 演算子に置き換わる手法は存在していません。
KeywordQuery に置き換える際には、この部分が制限事項となりますことをご理解、ご了承ください。

 

KQL の演算子 (AND NOT OR)

SQL 構文において、検索条件の組み合わせを色々と指定できましたが、これらは KQL においても条件の組み合わせを細かく指定が可能です。

author:"John Smith" AND filetype:docx

 

4. 管理プロパティを使用した並べ替えについて

SQL 構文で Order By 句で指定していた並べ替えについては、KeywodQuery.SortList プロパティに管理プロパティを指定することで代替処理が実装可能となります。

  myQuery.SortList.Add("Title", SortDirection.Descending);

タイトル : KeywordQuery.SortList property
アドレス : https://msdn.microsoft.com/en-us/library/microsoft.office.server.search.query.keywordquery.sortlist.aspx

ただし、管理プロパティが検索結果として "並べ替え可能" であるかどうかについては、管理プロパティの設定を確認しておく必要があります。
この点につきましては、上述の Technet ページである "SharePoint Server 2013 の検索スキーマの概要" をご確認ください。

 

次回予告

SQL 構文が使用できなくなり、取り急ぎキーワード構文に移行する方法については本投稿でご紹介しました。
ここで、Fast Query Language (FQL) はどうなのか?FQL だと制限になっている機能を実現できるのでは?と思われる方もいらっしゃると思います。FQL の使用につきましては、次回ご紹介させていただければと思います。

今回の投稿は以上になります。