SharePoint でクエリを絞り込む
検索のクエリや結果を処理している場合の、SharePoint クエリ絞り込み機能をプログラム的に使用する方法の詳細です。
エンドユーザーがクエリを行う場合に、それに関連する絞り込みオプションをエンドユーザーに提供するためにクエリ絞り込み機能を使用できます。 これらの機能により、検索結果から計算した絞り込みデータを使用して検索結果にエンドユーザーがドリルダウンできるようにします。 絞り込みデータは、検索クエリのすべての結果の管理プロパティ統計集計に基づいて、インデックス データによって計算します。
一般に、クエリ絞り込みは、アイテムに表示される作成日、作成者、ファイルの種類など、インデックス付きアイテムに関連付けられたメタデータに使用されます。 絞り込みオプションを使用すれば、クエリを絞り込んで、特定の期間に作成されたアイテムのみ表示したり、特定のファイルの種類のアイテムのみ表示したりすることができます。
クエリ オブジェクト モデルで絞り込み条件を使用する
クエリ絞り込みに関係のあるクエリは次の 2 つです。
- エンド ユーザーのクエリに絞り込み条件仕様を追加することで、検索結果に一連の 絞り込み条件 を返すように要求できます。 絞り込み条件仕様は Refiners プロパティへの入力です。 このクエリは検索インデックスに対して実行されます。 検索結果は、該当する結果と絞り込みデータから構成されます。
- 絞り込みクエリを作成することによって、絞り込みデータを使用して検索結果を掘り下げることができます。 最終的な検索結果がエンド ユーザーの元のクエリ テキストと絞り込みデータから選択した絞り込みオプションの両方の要件を満たすように、 クエリに RefinementFilters プロパティを追加します。
以下のセクションでは、これらの手順について詳細に説明し、コード例を示します。
絞り込み条件仕様でエンド ユーザーのクエリに絞り込み条件を追加する
KeywordQuery クラスの Refiners プロパティを使用して、要求されたクエリ絞り込み条件を指定できます。 次の構文を使用して、要求されるクエリ絞り込み条件を指定します。
<refiner>[,<refiner>]*
各 refiner
の形式は次のとおりです。
<refiner-name>[(parameter=value[,parameter=value]*)]?
ここで、
<refiner-name>
は、絞り込み条件に関連付けられている管理プロパティの名前です。 この管理プロパティは、検索スキーマで Refinable または Sortable に設定する必要があります。- オプションの
parameter=value
のペアのリストは、名前付き絞り込み条件の既定ではない構成値を指定します。 かっこ内に絞り込み条件のパラメーターがリストされていない場合は、検索スキーマ構成によって既定の設定が指定されます。 表 1 に、parameter=value
のペアの設定可能な値を示します。
注:
絞り込み条件を指定する場合の最小要件は、管理プロパティである refiner-name
を指定することです。
例
Refiners = "FileType"
また、高度な構文を使用して絞り込み条件の設定を調整することもできます。
Refiners = "FileType,Write(discretize=manual/2013-01-01/2013-08-22/2013-09-15/2013-09-21/2013-09-22),companies"
表 1: 絞り込み条件のパラメーター一覧
パラメーター | 説明 |
---|---|
deephits |
絞り込みの計算で根拠として使用されるヒットの既定の数をオーバーライドします。 絞り込み条件が生成されると、クエリのすべての結果が検証されます。 通常、このパラメーターを使用すると検索パフォーマンスが向上します。 構文 deephits=<integer value> 例 price(deephits=1000) 注: この制限は各インデックス パーティション内で適用されます。 複数の検索パーティションにまたがる集計により、評価される実ヒット数はこの値よりも大きくなります。 |
分離 |
数値絞り込み条件用のカスタム間隔 (絞り込みビン) を指定します。 構文 discretize=manual/<threshold>/<threshold>[/<threshold>]* 例 write(discretize=manual/2013-01-01/2013-08-22/2013-09-15/2013-09-21/2013-09-22) <threshold> 属性は各絞り込みビンのしきい値を指定します。 指定された最初のしきい値以下のすべてに対して 1 つの間隔、連続する各しきい値の間に 1 つの間隔、最後のしきい値以上のすべてに対して 1 つの間隔があります。 DateTime 型の絞り込み条件については、以下の ISO 8601 互換の形式に従ってしきい値を指定します。
|
並べ替え |
文字列絞り込み条件内でビンを並べ替える方法を定義します。 構文 sort=<property>/<direction> 属性は以下を実行します。
sort=name/ascending 既定: 頻度/降順 |
filter |
文字列型の絞り込み条件内のビンがクライアントに返される前にどのようにフィルターされるかを定義します。 構文 filter=<bins>/<freq>/<prefix>[<levels>] 属性は以下を実行します。
|
カットオフ |
深い文字列絞り込み条件のために移動し処理される必要があるデータを制限します。 この絞り込み条件は、もっとも関連性が高い値 (bin) のみを返すために設定することができます。 注: このカットオフ フィルター処理は、各インデックス パーティション内で実行されます。 これが、結果側のフィルター処理のみ行う filter パラメーターと違うところです。 2 つのパラメーターは組み合わせることができます。 構文 cutoff=<frequency>/<minbins>/<maxbins> 属性は以下を実行します。
|
例: 絞り込み条件を追加する
次の CSOM の例は、3 つの絞り込み条件 ( FileType、 Write、 Companies) をプログラムで要求する方法を示しています。 Write は、アイテムの最終変更日を示し、高度な構文を使用して固定サイズの日付/時刻 bin を返します。
using (var context = new ClientContext("http://<serverName>/<siteCollectionPath>"))
{
var query = new KeywordQuery(context)
{
QueryText = "home",
Refiners = "FileType,Write(discretize=manual/2013-01-01/2013-08-22/2013-09-
15/2013-09-21/2013-09-22),companies"
};
var executor = new SearchExecutor(context);
var results = executor.ExecuteQuery(query);
context.ExecuteQuery();
ResultTable relevantResultsTable = results.Value[0];
ResultTable refinerResultsTable = results.Value[1];
Console.WriteLine(refinerResultsTable.RowCount + " refinement options:");
foreach (var refinementOption in refinerResultsTable.ResultRows)
{
Console.WriteLine("RefinerName: '{0}' RefinementName: '{1}'
RefinementValue: '{2}' RefinementToken: '{3}' RefinementCount: '{4}'",
refinementOption["RefinerName"],
refinementOption["RefinementName"],
refinementOption["RefinementValue"],
refinementOption["RefinementToken"],
refinementOption["RefinementCount"]
);
}
}
検索結果の絞り込みデータの概要
クエリで管理プロパティのクエリ絞り込みを有効にした場合、クエリ結果には絞り込みビンに分割された絞り込みデータが含まれます。このデータは、ResultTableCollection 内の RefinementResults テーブル (RefinementResults) にあります。 1 つの絞り込みビンは、管理プロパティの特定の値または値範囲を表します。 RefinementResults テーブルには、絞り込みビンごとに 1 行が含まれており、表 2 で指定されている列が含まれています。
表 2: 絞り込み bin で返されるデータ
パラメーター | 説明 |
---|---|
RefinerName | クエリ絞り込み条件の名前。 |
RefinementName | この絞り込み bin を表す文字列。 この文字列は通常、検索結果ページで、ユーザーに絞り込みオプションを示すときに使用されます。 |
RefinementValue | 絞り込みを表す、実装に固有の書式設定がされた文字列。 このデータはデバッグのために返されるもので、通常、クライアントは必要としません。 |
RefinementToken | 絞り込みクエリを実行するときに RefinerName と共に使用する絞り込み bin を表す文字列。 |
RefinementCount | この絞り込み bin の結果カウント。 このデータは、この絞り込み bin に含まれる特定の管理プロパティのための値を持つ検索結果での、アイテムの数 (複製を含む) を表します。 |
例: 絞り込みデータ
次の表 3 には、絞り込みデータの行が 2 行示されています。 最初の行には、ファイルの種類が HTML である、インデックス付きアイテムの絞り込みデータが含まれています。 2 番目の行には、最終変更時刻が 2013/09/21 から 2013/09/22 の間である、インデックス付きアイテムの絞り込みデータが含まれています。
表 3: 絞り込みデータの形式と内容
RefinerName | RefinementName | RefinementValue | RefinementToken | RefinementCount |
---|---|---|---|---|
FileType | HTML | HTML | "????68746d6c" | 50553 |
書き込み | From 2013-09-21T00:00:00Z up to 2013-09-22T00:00:00Z | From 2013-09-21T00:00:00Z up to 2013-09-22T00:00:00Z | range(2013-09-21T00:00:00Z, 2013-09-22T00:00:00Z) | 37 |
絞り込みクエリを作成する
検索結果には、文字列値または値範囲の形式で絞り込みオプションが表示されます。 各文字列値または数値範囲は絞り込みビンと呼ばれ、各絞り込みビンには 関連付けられた RefinementToken 値があります。 絞り込みオプションは、 RefinerName 値によって提供される管理プロパティに関連付けられています。
RefinementToken と RefinerName の 2 つの値を連結して refinement filter 文字列を作成します。 この文字列は、管理プロパティに絞り込み bin 内の値があるアイテムのみが含まれるように検索結果アイテムを限定するのに使用できるフィルターとなります。 まとめると次のようになります。
refinement filter = <RefinerName>:<RefinementToken>
KeywordQuery クラスの RefinementFilters プロパティに絞り込みフィルターを追加することで、絞り込みクエリに 1 つ以上の絞り込みフィルターを指定できます。 複数の絞り込みフィルターを使用すると、検索結果に複数レベルのドリルダウンを提供したり、複数値のプロパティに絞り込みを適用したりできます。 たとえば、2 人の作成者 (それぞれ絞り込みビンで表される) を持つアイテムに対してクエリを絞り込むことができますが、作成者が 1 人しかないアイテムは除外できます。
例 1: HTML タイプのファイルに対して絞り込み済みクエリを作成する
以下の CSOM 例では、検索結果を HTML タイプのファイルに限定するように、プログラム的に絞り込みを行う方法を示しています。 「例: 絞り込みデータ」で説明されているように、この絞り込みオプションに関連する絞り込みデータでは、RefinerName が Filetype に設定され、RefinementTokenが "???? に設定されています68746d6c"。
using (var context = new ClientContext("http://<serverName>/<siteCollectionPath>"))
{
var query = new KeywordQuery(context)
{
QueryText = "home"
};
query.RefinementFilters.Add("FileType:\\"????68746d6c\\"");
var executor = new SearchExecutor(context);
var results = executor.ExecuteQuery(query);
context.ExecuteQuery();
ResultTable relevantResultsTable = results.Value[0];
var resultCount = 1;
foreach (var relevantResult in relevantResultsTable.ResultRows)
{
Console.WriteLine("Relevant result number {0} has file type {1}.",
resultCount, relevantResult["FileType"]);
resultCount++;
}
}
例 2: 以前に取得した絞り込みデータを使用した絞り込みクエリの作成
次の CSOM の例では、絞り込み条件仕様でクエリを実行し、続いて使用される絞り込みデータを作成して絞り込みを実行する方法を示しています。 この例では、最初の絞り込みオプションを選択するエンド ユーザーのプロセスをシミュレートしています。
using (var context = new ClientContext("http://<serverName>/<siteCollectionPath>"))
{
// Step 1: Run the query with refiner spec to provide refinement data in search result
var query = new KeywordQuery(context)
{
QueryText = "home",
Refiners = "FileType,Write(discretize=manual/2013-01-01/2013-08-22/2013-09-15/2013-09-21/2013-09-22),companies"
};
Console.WriteLine("Run query '{0}' with refiner spec '{1}'.", query.QueryText, query.Refiners);
var executor = new SearchExecutor(context);
var results = executor.ExecuteQuery(query);
context.ExecuteQuery();
// The query has been run and we can now look at the refinement data, to view the
// refinement options
ResultTable relevantResultsTable = results.Value[0];
ResultTable refinerResultsTable = results.Value[1];
Console.WriteLine("Got back {0} refinement options in the result:",
refinerResultsTable.RowCount);
foreach (var refinementOption in refinerResultsTable.ResultRows)
{
Console.WriteLine("RefinerName: '{0}' RefinementName: '{1}'
RefinementValue: '{2}' RefinementToken: '{3}' RefinementCount: '{4}'",
refinementOption["RefinerName"],
refinementOption["RefinementName"],
refinementOption["RefinementValue"],
refinementOption["RefinementToken"],
refinementOption["RefinementCount"]
);
}
// Step 2: Run the refined query with refinement filter to drill down into
// the search results. This example uses the first refinement option in the refinement
// data, if available. This simulates an end user selecting this refinement option.
var refinementOptionArray = refinerResultsTable.ResultRows.ToArray();
if (refinementOptionArray.Length > 0)
{
var firstRefinementOption = refinementOptionArray[6];
// Construct the refinement filter by concatenation
var refinementFilter = firstRefinementOption["RefinerName"] + ":" +
firstRefinementOption["RefinementToken"];
var refinedQuery = new KeywordQuery(context)
{
QueryText = query.QueryText
};
refinedQuery.RefinementFilters.Add(refinementFilter);
refinedQuery.SelectProperties.Add("FileType");
refinedQuery.SelectProperties.Add("Write");
refinedQuery.SelectProperties.Add("Companies");
Console.WriteLine("Run query '{0}' with refinement filter '{1}'",
refinedQuery.QueryText, refinementFilter);
var refinedResults = executor.ExecuteQuery(refinedQuery);
context.ExecuteQuery();
ResultTable refinedRelevantResultsTable = refinedResults.Value[0];
var resultCount = 1;
foreach (var relevantResult in refinedRelevantResultsTable.ResultRows)
{
Console.WriteLine("Relevant result number {0} has FileType='{1}',
Write='{2}', Companies='{3}'",
resultCount,
relevantResult["FileType"],
relevantResult["Write"],
relevantResult["Companies"]
);
resultCount++;
}
}
}