I have retrieve SharePoint search results using javascript on SharePoint Online. But it returns maximum 500 search results for any query. I have set RowLimit to 10000:

var keywordQuery = new Microsoft.SharePoint.Client.Search.Query.KeywordQuery(context);
    keywordQuery.set_queryText("queryText here");
    keywordQuery.set_trimDuplicates(false);

    keywordQuery.set_rowLimit(10000); // <<<< Not Working

    var searchExecutor = new Microsoft.SharePoint.Client.Search.Query.SearchExecutor(context);
    results = searchExecutor.executeQuery(keywordQuery);

    context.executeQueryAsync(onQuerySuccess, onQueryFail);

But it's not working and returns only 500 search results.

Any solution to increase search result limit on SharePoint Online ?

  • 1
    you can not get more than 500 result at time – Rajesh Joshi Feb 18 '17 at 5:54
  • is it ok if I post answer which uses REST api or CSOM C# ? Unfortunately i dont have a JSOM sample, but probably you can work it out ? – Gautam Sheth Feb 18 '17 at 8:23
  • @GautamSheth , No Problem. Answer it.. – Ronak Patel Feb 18 '17 at 8:59

500 is the max limit, a defined boundary, of the number of items which will be fetched via Search API in SP Online. It cant be changed via powershell. If you expect more than 500 results, you need to get it via paging.

Search limits for SharePoint Online

If it was SP Onprem, you can increase the max row limit via powershell as below, but will come at some cost to performance:

$ssa = Get-SPEnterpriseSearchServiceApplication
$ssa.MaxRowLimit = 10000
$ssa.Update()

But in SPOnline, we cant modify this limit yet.

Using REST API, you can follow Vadim's excellent gist utility which fetches all search results via paging. As mentioned in Brent's answer, you need to specify the start row when you are going to use paging.

Gist utility:

function search(queryText,rowLimit,startRow,allResults)
{
    var allResults = allResults || [];
    var url = _spPageContextInfo.siteAbsoluteUrl + "/_api/search/query?querytext='" + queryText + "'&rowlimit=" + rowLimit + "'&startrow=" + startRow;
    return $.getJSON(url).then(function(data) {
           var relevantResults = data.PrimaryQueryResult.RelevantResults;
           allResults = allResults.concat(relevantResults.Table.Rows);
           if (relevantResults.TotalRows > startRow + relevantResults.RowCount) {
               return search(queryText,rowLimit,startRow+relevantResults.RowCount,allResults);
           }    
           return allResults;
    });
}

Usage:

search('some query text',500,0).done(function(results){
       //iterate through the results
       for(var i = 0;i < results.length;i++){
           console.log(results[i]);
       }
});

If you thinking of using managed CSOM, then you can use the below method:

private static ResultTable GetSearchResults(int startIndex,ClientContext clientContext)
{
    ClientResult<ResultTableCollection> results = null;
    try
    {
        KeywordQuery keywordQuery = new KeywordQuery(clientContext);

        SearchExecutor searchExecutor = new SearchExecutor(clientContext);

        keywordQuery.StartRow = startIndex;//gets or sets the first row of information from the search results

        keywordQuery.QueryText = "queryText here";

        keywordQuery.RowLimit = 500;

        keywordQuery.RowsPerPage = 500;

        keywordQuery.TrimDuplicates = false;

        keywordQuery.Timeout = 10000; //10 minutes

        // execute the query and load the results into a collection
        results = searchExecutor.ExecuteQuery(keywordQuery);

        clientContext.ExecuteQuery();

        //clientContext.ExecuteQueryWithIncrementalRetry(5, 30000); //5 retries, with a base delay of 30 secs.

        return results.Value.FirstOrDefault(v => v.TableType.Equals(KnownTableTypes.RelevantResults));
    }
    catch (Exception)
    {
        throw;
    }
}

How to use it :

static void Main(string[] args)
{
    using (ClientContext clientContext = new ClientContext("https://sitecollectionurl"))
    {
        #region Build Data Dable
        DataTable resultDataTable = new DataTable();

        DataColumn titleCol = new DataColumn("Title");
        DataColumn pathCol = new DataColumn("Path");

        resultDataTable.Columns.Add(titleCol);
        resultDataTable.Columns.Add(pathCol);

        #endregion

        int currentRowIndex = 0;

        var resultTable = GetSearchResults(0, clientContext);

        if (resultTable != null && resultTable.TotalRowsIncludingDuplicates > 0)
        {
            while (resultTable.TotalRowsIncludingDuplicates > resultDataTable.Rows.Count)
            {
                foreach (var resultRow in resultTable.ResultRows)
                {
                    DataRow row = resultDataTable.NewRow();
                    row["Title"] = resultRow["Title"];
                    row["Path"] = resultRow["Path"];
                    resultDataTable.Rows.Add(row);
                }

                //Update the current row index
                currentRowIndex = resultDataTable.Rows.Count;

                resultTable = null;

                resultTable = GetSearchResults(currentRowIndex, clientContext);

                if (resultTable != null && resultTable.TotalRowsIncludingDuplicates > 0)
                {
                    if (resultTable.RowCount <= 0)
                    break;
                }
                else
                    break;
            }
        }

        string totalResults = resultDataTable.Rows.Count;
    }

}

Reference - SP 2013 search results paging

  • Thanks for the answer. I have tried with Vadim's Javascript solution. I am searching hostweb from my app. It's throws error: Failed to load resource: the server responded with a status of 403 (Forbidden) . While same script working fine on hostweb page. I have given full control permission on Web, List, Site Collection in app. – Ronak Patel Feb 20 '17 at 5:17
  • You also need to give it permission to search. Check this image: i.stack.imgur.com/SlOzQ.png – Gautam Sheth Feb 20 '17 at 6:01
  • I have already given search permission. My JSOM code working fine. – Ronak Patel Feb 20 '17 at 6:48
  • Thats quite strange, not sure what could be the issue. Can you try with tenant read permission, could be an overkill though ? – Gautam Sheth Feb 20 '17 at 7:18
  • Already tried It. Not working. Same error. – Ronak Patel Feb 20 '17 at 7:42

You would have to setup a recursive loop to requery the list. Since you know you're limited to 500 records per query, you can set the start row via keywordQuery.set_startRow(startRowValue);

  • This is correct way. – vikbehal Feb 18 '17 at 12:00

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.