1. 検索を操作する

xConnect検索結果のページ分割

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

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

結果は、次の2つの方法のいずれかでページ分割できます。

  • 推奨されるGetBatchEnumerator() / GetBatchEnumeratorSync() 方法を使用する

  • Skip()方法とTake()方法を使用する

ページを使用しない場合、パフォーマンスを維持するために、結果の数はデフォルトのバッチサイズに制限されます。データをエクスポートするには、データ抽出機能を使用する必要があります。

ページネーションとパフォーマンス

多数の結果をスキップすることは、非常に大きなバッチを要求するのと同じくらい非効率的です。999990レコードをスキップし、レコード #999990をレコード #1000000に表示するには、検索プロバイダーは最初の999990レコードを検索して並べ替える必要があります。これらの999990を10個ずつスキップした場合でも、各Skip() は新しいクエリとして扱われ、パフォーマンスへの影響がますます深刻になります。これは、SolrとAzure Searchに当てはまります。

.GetBatchEnumerator() メソッドと .GetBatchEnumeratorSync() メソッドは、シーケンシャル バッチを反復処理するために使用されるカーソルを返します。各バッチはカーソルマークに関連付けられています。カーソルマークはバイト配列で表され、大きな結果セットを反復処理するときに位置をブックマークします。これらの方法は、既に表示された結果をスキップすることでパフォーマンスを向上させます - つまり、レコード #999990をレコード #1000000に表示すると、最初の999990レコードは無視されます。

カーソルマークを使用するときは、次の点に注意してください。

  • カーソルマークでは、レコード #999990に直接スキップすることはできません - このポイントに到達するまで、すべての結果を反復処理する必要があります。パフォーマンスの向上は、新しいバッチが返されるたびに以前に表示された結果を見つけて並べ替える必要がないことに起因します。

  • カーソルマークは存続期間が短く、モデルの変更に耐性がありません。したがって、ページネーションUIのカーソル マークに頼るべきではありません。たとえば、30個のバッチを反復処理する場合は、30個のカーソル マークを保持しず、それらをページ番号として扱います。

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

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

詳細については、 Solrでの結果のページネーション (特にPerformance Problems with “Deep Paging”の項) を参照してください。

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

.Skip() と .タケ()

連絡先やインタラクションの小さなサブセットを通じて交流したい場合は、.Skip() and .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<WebVisit>(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<WebVisit>(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<WebVisit>(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<WebVisit>(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<WebVisit>(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<WebVisit>(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);
                }
            }
        }
    }
}
この記事を改善するための提案がある場合は、 お知らせください!