Pagination for large result sets

If you have a large number of search results (for example, over 50,000) to page through in a query, it is recommended to use the approach explained in this article instead of the approach of StartRow. This approach uses sorting on [docid] in ascending order and uses a query restriction on the IndexDocId value with an increasing value of IndexDocID for each new page.

The advantages of this approach are:

  • It provides pagination with better performance
  • It does not have a limit on the number of pages (if you use the approach of StartRow and the StartRow value is greater than 50,000, there is a risk of being throttled by SharePoint)

Here is an example of using this approach:

For Page 1, issue a query with sort on [docid] in ascending order:

GET http://{site_url}/_api/search/query?querytext='sharepoint'&sortlist='[docid]:ascending'

The result of this query should contain the following content:

...
<d:element m:type="SP.SimpleDataRow">
    <d:Cells>
        ...
        <d:element m:type="SP.KeyValue">
            <d:Key>DocId</d:Key>
            <d:Value>10</d:Value>
            <d:ValueType>Edm.Int64</d:ValueType>
        </d:element>
        ...

Get the DocId value of the last entry in the result. You should be able to find DocId under SP.SimpleDataRow. Let's say the DocId value is 10. You will use that as the DocID restriction for page 2:

For Page 2, use the following query, where you need to continue using sortlist on DocId in ascending order, but also add an IndexDocId restriction:

GET http://{site_url}/_api/search/query?querytext='sharepoint indexdocid>10'&amp;sortlist='[docid]:ascending'

Let's say the DocId value of the last entry in the result is 20.

For Page 3, continue the query with the same pattern as previous page:

GET http://{site_url}/_api/search/query?querytext='sharepoint indexdocid>20'&amp;sortlist='[docid]:ascending'

And so on for the rest of the pages.

To use the same approach in CSOM, see the following example:

...
if (startRow == 0) // When issueing the query for first time, we don't have a DocId value yet
    keywordQuery.QueryText = "sharepoint";
else  // Putting the IndexDocId first and then the 'actual' query matters (in this case searching for the keyword 'sharepoint')
    keywordQuery.QueryText = string.Format("IndexDocId>{0} AND (sharepoint)", startRow);
keywordQuery.EnableSorting = true;
keywordQuery.SortList.Add("[DocId]", Microsoft.SharePoint.Client.Search.Query.SortDirection.Ascending);
...

Note

When using the SortList in search queries, the fieldname being used must be enclosed by brackets (e.g. [DocId]).