1. 検索に関する研究

xConnect検索結果のページング

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

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

結果をページ付けする方法は2通りあります:

  • 推奨されている GetBatchEnumerator() / GetBatchEnumeratorSync() 方法を使う
  • Skip()法とTake()法の利用

ページ分けをしない場合は、パフォーマンスを保つために結果数をデフォルトのバッチサイズに制限します。データをエクスポートするには、データ抽出機能を使うべきです。

ページと演奏

大量の結果をスキップすることは、非常に大きなバッチを要求するのと同じくらい非効率的です。999990件のレコードをスキップし、#99990を#10000000に表示するためには、検索提供者は最初の999990件を見つけてソートしなければなりません。たとえ10件ずつの99990件をスキップしても、各Skip() は新しいクエリとして扱われ、パフォーマンスへの影響がますます深刻になります。これはSolrやAzure Searchでも当てはまります。

.GetBatchEnumerator()および.GetBatchEnumeratorSync()メソッドは、連続バッチを順番に進めるために使われるカーソルを返します。各バッチにはカーソルマークが関連付けられています。カーソルマークはバイト配列で表され、大規模な結果セットを反復する際に位置情報ブックマークを付けます。これらの方法は、すでに見た結果をスキップすることでパフォーマンスを向上させます。つまり、レコード#99990をレコード#10000000に表示する際、最初の999990レコードは無視されます。

cursor-mark-11.png

カーソルマークを使用する際には以下の点を念頭に置いてください:

  • カーソルマークではレコード#999990に直接スキップすることはできません。この点まですべての結果を繰り返し確認する必要があります。パフォーマンス向上は、新しいバッチが返されるたびに既に見た結果を探して並べ替える必要がないことにあります。
  • カーソルマークは寿命が短く、モデルの変更に耐性はありません。したがって、ページ付けのUIでカーソルマークに頼るべきではありません。例えば、30バッチを繰り返し処理する場合、30カーソルマークを永続化してページ番号として扱わないでください。

カーソルマークはエラーが発生した場合に検索操作を再開するために使用できます。例えば、1000バッチを反復処理中にバッチ999中にエラーが発生した場合、その時点でカーソルマークを保持することでバッチ999で再開できます。

ユーザーインターフェースで深いページングをサポートする場合は、無限スクロールの使用を検討してください。これにより結果セットを前後にページングする必要がなくなり、

詳細については、Solrの結果のページ付け 、特に 「ディープページングのパフォーマンス問題」のセクションを参照してください。

カーソルマークはシャード環境で特に重要になり、各シャードは100件の結果を返す必要があります。その後、100件ずつの3回の結果が集約され、上位100件がクライアントに返されます。

cursor-mark-21.png

浅いページ展開 と 。スキップ() と 。テイク()

ごく一部の接触や相互作用を通じてインターテートしたい場合、.Skip() と .Take() の方法を使うことは許容されます。

using Sitecore.XConnect.Collection.Model; using System.Linq; using Sitecore.XConnect;

namespace Documentation { public class SearchInteractionSkipTake { // Async example // Example query string: searchresults?page=4&pageSize=10 public async void ExampleAsync(int pageSize, int page) { using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient()) { try { var skip = pageSize * (page - 1);

IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions .Where(x => x.GetFacet(CollectionModel.FacetKeys.WebVisit).Browser.BrowserMajorName == "Chrome") .Skip(skip) .Take(pageSize);

var results = await queryable.ToSearchResults();

var count = results.Count; // Actual count of all results

var interactions = await results.Results.Select(x => x.Item).ToList();

} catch (XdbExecutionException ex) { // Handle exception } } }

public void ExampleSync(int pageSize, int page) { using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient()) { try { var skip = pageSize * (page - 1);

IAsyncQueryable<Sitecore.XConnect.Interaction> queryable = client.Interactions .Where(x => x.GetFacet(CollectionModel.FacetKeys.WebVisit).Browser.BrowserMajorName == "Chrome") .Skip(skip) .Take(pageSize);

// NOTE: No sync version of ToSearchResults exists // and it is the only way to get a count of actual results var results = Sitecore.XConnect.Client.XConnectSynchronousExtensions.SuspendContextLock(queryable.ToSearchResults);

var items = results.Results.Select(x => x.Item); // Interactions var count = results.Count; // Total count } catch (XdbExecutionException ex) { // Handle exception } } } } }

!注常にSkip().Take()に電話し、決してTake().Skip()しないでください。

深いページ化 。GetBatchEnumerator()

以下の例は、大量の結果を反復処理する際の .GetBatchEnumerator() / .GetBatchEnumeratorSync() の使い方を示しています。

using Sitecore.XConnect.Collection.Model; using System.Collections.Generic; using System.Linq; using Sitecore.XConnect; using Sitecore.XConnect.Client;

namespace Documentation { public class SearchInteractionCursorBasic { // Async example public async void ExampleAsync() { using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient()) { try { var results = client.Interactions .Where(x => x.GetFacet(CollectionModel.FacetKeys.WebVisit).Browser.BrowserMajorName == "Chrome");

var enumerator = await results.GetBatchEnumerator(200);

var numberOfBatches = 0;

// Enumerate through batches of 200 while (await enumerator.MoveNext()) { numberOfBatches++;

// Loop through interactions in current batch foreach (var interaction in enumerator.Current) { // Do something for each interaction } } } catch (XdbExecutionException ex) { // Handle exception } } }

// Sync example public void ExampleSync() { using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient()) { try { var results = client.Interactions .Where(x => x.GetFacet(CollectionModel.FacetKeys.WebVisit).Browser.BrowserMajorName == "Chrome");

var numberOfBatches = 0;

var enumerator = results.GetBatchEnumeratorSync(200);

// Enumerate through batches of 200 while (enumerator.MoveNext()) { numberOfBatches++;

// Loop through interactions in current batch foreach (var interaction in enumerator.Current) { // Do something for each interaction } } } catch (XdbExecutionException ex) { // Handle exception } } } } }

以下の例は、ブックマークを永続化し、例外が発生した場合に検索クエリを再開する方法を示しています。

using Sitecore.XConnect.Collection.Model; using System.Collections.Generic; using System.Linq; using Sitecore.XConnect; using Sitecore.XConnect.Client;

namespace Documentation { public class SearchInteractionCursor { // Async example public async void ExampleAsync(byte bookmark) { using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient()) { byte bookmarkSave = null;

try { var results = client.Interactions .Where(x => x.GetFacet(CollectionModel.FacetKeys.WebVisit).Browser.BrowserMajorName == "Chrome");

var enumerator = await results.GetBatchEnumerator(200);

var numberOfBatches = 0;

// Enumerate through batches of 200 while (await enumerator.MoveNext()) { bookmarkSave = enumerator.GetBookmark(); numberOfBatches++;

// Loop through interactions in current batch foreach (var interaction in enumerator.Current) { // Do something for each interaction } } } catch (XdbExecutionException ex) { // Retry using saved bookmark ExampleAsync(bookmarkSave); } } }

// Sync example public void ExampleSync(byte bookmark) { using (Sitecore.XConnect.Client.XConnectClient client = Sitecore.XConnect.Client.Configuration.SitecoreXConnectClientConfiguration.GetClient()) { byte bookmarkSave = null;

try { var results = client.Interactions .Where(x => x.GetFacet(CollectionModel.FacetKeys.WebVisit).Browser.BrowserMajorName == "Chrome");

var numberOfBatches = 0;

var enumerator = results.GetBatchEnumeratorSync(200);

// Enumerate through batches of 200 while (enumerator.MoveNext()) { bookmarkSave = enumerator.GetBookmark(); numberOfBatches++;

// Loop through interactions in current batch foreach (var interaction in enumerator.Current) { // Do something for each interaction } } } catch (XdbExecutionException ex) { // Handle exception ExampleSync(bookmarkSave); } } } } }

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