If you are developing a custom result page, some of the key requirements (in addition to showing relevant results) that are common across many types of projects are:

  1. Showing the total number of search results based on the submitted keyword or query so that you can show some statistics like Results 1-10 of 572
  2. Showing links for page numbers to move backwards and forwards (e.g. < Back, 1, 2, 3, 4, 5, Next >). Getting the page count correct is again dependent of getting total results count correct.

The SharePoint Object Model (OM) provides two types of classes to query against it content: KeywordQuery and FullTextSqlQuery. These queries have properties StartRow and RowLimit. Both of these queries get us result in ResultTable class and this class has one property TotalRows. These properties are defined below:

  • StartRow: Gets or sets first row included in the search results.
  • RowLimit: Gets or sets the maximum number of rows returned in the search results.
  • TotalRows: Gets the number of rows in the search query result table.

With the above understanding, isn't it too simple to implement to get both of the points – 1 and 2 stated above. Basically, your paging would be like this .. Result <StartRow> to <StartRow + RowLimit> of <TotalRows>. And based on TotalRows, you can show the links for pages to be displayed.

However, this is not that simple. It's very difficult for any search engine (including web search engines such as Live or Google) to get the exact number of total results found as it's very time consuming scheme. So, most search engines (including MOSS) perform only an "estimate" to provide total number of results. Hence, the value of TotalRows property can change for the same keyword. The value is more accurate when the StartRow is towards the end of search results. Hence any logic to display links for search pages can fail here. I recommend the following approach here:

The links for "page" numbers may get unstable. For example, let us say, you got total rows as 100 and you always show links for page 1, 2, 3, 4 and 5. But let us say, actual result is 27 only. Which would mean if user clicks on page "4" , you'll fire a query for item 31 to 40 and you'll get zero results. At this point rather than showing page with zero results, do the following:

  1. Get the Total rows from the same result table. This time it should give the correct value (27 as it is close to end). Confirm it's correctness by checking the value of property IsTotalRowsExact.
  2. If it's correct, then just show the last page which is 3 (and make links for page, 4, 5 and "Next" as invisible)

Though, the approach seems "crude" , but it's one of the most efficient and least invasive way to achieve this functionality. Even internet search engines such as Live and Google employ the same technique.

There are some other approach that you can use to get the numbering correct as provided in the following blogs:

  1.  To round  the total results number off to some value (for consistency): Results count and custom paging [ http://blogs.pointbridge.com/Blogs/dupont_thomas/Pages/Post.aspx?_ID=7 ]
  2. Use Query.TotalRowsExactMinimum to show how many page numbers to show from current page: Understanding Total Hits & Paging in the MOSS 2007 Search API (http://sharepointsearch.com/cs/blogs/enterprisesearch/archive/2008/05/22/understanding-total-hits-amp-paging-in-the-moss-2007-search-api.aspx )