SharePoint Search provides REST query API that can be used to access search results. In other words SharePoint search may be as a read-only data source which provide all the data you have (list items, documents, user profiles, and Office 365 services based on SharePoint such as Planner, Groups, Project Online and others)
In this post I show how use SharePoint Search REST API to build up custom solutions.
There are many APIs to process search queries in SharePoint 2013/2016/Online:
Parameters of query (Source: SharePoint Search REST API overview)
Parameter | Type | Default Value | Description |
---|---|---|---|
querytext | string | null | A string that contains the text for the search query. |
queryTemplate | string | null | A string that contains the text that replaces the query text, as part of a query transform. |
enableInterleaving | bool | true | A Boolean value that specifies whether the result tables that are returned for the result block are mixed with the result tables that are returned for the original query. true to mix the ResultTables; otherwise, false. The default value is true. Change this value only if you want to provide your own interleaving implementation. |
sourceId | Guid | new Guid() | The result source ID to use for executing the search query. |
rankingModelId | string | null | The ID of the ranking model to use for the query. |
startRow | int | 0 | The first row that is included in the search results that are returned. You use this parameter when you want to implement paging for search results. |
rowLimit | int | 10 | The maximum number of rows overall that are returned in the search results. Compared to RowsPerPage, RowLimit is the maximum number of rows returned overall. |
rowsPerPage | int | 0 | The maximum number of rows to return per page. Compared to RowLimit, RowsPerPage refers to the maximum number of rows to return per page, and is used primarily when you want to implement paging for search results. |
selectProperties | string | null | The managed properties to return in the search results. To return a managed property, set the property's retrievable flag to true in the search schema. For GET requests, you specify the SelectProperties parameter in a string containing a comma-separated list of properties. For POST requests, you specify the SelectProperties parameter as a string array. |
culture | int | -1 | The locale ID (LCID) for the query |
refinementFilters | string | null | The set of refinement filters used when issuing a refinement query. For GET requests, the RefinementFilters parameter is specified as an FQL filter. For POST requests, the RefinementFilters parameter is specified as an array of FQL filters. |
refiners | string | null | The set of refiners to return in a search result. |
hiddenConstraints | string | null | The additional query terms to append to the query. |
sortList | string | null | The list of properties by which the search results are ordered. |
enableStemming | bool | true | A Boolean value that specifies whether stemming is enabled. |
trimDuplicates | bool | true | A Boolean value that specifies whether duplicate items are removed from the results. |
timeout | int | 15000 | The amount of time in milliseconds before the query request times out. The default value is 30000. |
enableNicknames | bool | false | A Boolean value that specifies whether the exact terms in the search query are used to find matches, or if nicknames are used also. |
enablePhonetic | bool | false | A Boolean value that specifies whether the phonetic forms of the query terms are used to find matches. |
enableFQL | bool | false | A Boolean value that specifies whether the query uses the FAST Query Language (FQL). |
hitHighlightedProperties | string | null | The properties to highlight in the search result summary when the property value matches the search terms entered by the user. For GET requests, Specify in a string containing a comma-separated list of properties. For POST requests, specify as an array of strings. |
bypassResultTypes | bool | true | A Boolean value that specifies whether to perform result type processing for the query. |
processBestBets | bool | true | A Boolean value that specifies whether to return best bet results for the query. |
clientType | string | null | The type of the client that issued the query. |
personalizationData | Guid | new Guid() | The GUID for the user who submitted the search query. |
resultsUrl | string | null | The URL for the search results page. |
queryTag | string | null | Custom tags that identify the query. You can specify multiple query tags, separated by semicolons. |
trimDuplicatesIncludeId | long | 0 | |
totalRowsExactMinimum | int | 0 | |
impressionId | string | null | |
properties | string | null | Additional properties for the query. GET requests support only string values. POST requests support values of any type. |
enableQueryRules | bool | true | A Boolean value that specifies whether to enable query rules for the query. |
summaryLength | int | 180 | The number of characters to display in the result summary for a search result. |
maxSnippetLength | int | 180 | The maximum number of characters to display in the hit-highlighted summary generated for a search result. |
desiredSnippetLength | int | 90 | The preferred number of characters to display in the hit-highlighted summary generated for a search result. |
uiLanguage | int | -1 | The locale identifier (LCID) of the user interface. |
blockDedupeMode | int | -3 | |
generateBlockRankLog | bool | false | A Boolean value that specifies whether to return block rank log information in the BlockRankLog property of the interleaved result table. A block rank log contains the textual information on the block score and the documents that were de-duplicated. |
enableSorting | bool | true | A Boolean value that specifies whether to sort search results. |
collapseSpecification | string | null | The managed properties that are used to determine how to collapse individual search results. Results are collapsed into one or a specified number of results if they match any of the individual collapse specifications. Within a single collapse specification, results are collapsed if their properties match all individual properties in the collapse specification. |
processPersonalFavorites | bool | true | A Boolean value that specifies whether to return personal favorites with the search results. |
enableOrderingHitHighlightedProperty | bool | false | A Boolean value that specifies whether the hit highlighted properties can be ordered. |
hitHighlightedMultivaluePropertyLimit | int | -1 | The number of properties to show hit highlighting for in the search results. |
queryTemplatePropertiesUrl | string | null | The location of the queryparametertemplate.xml file. This file is used to enable anonymous users to make Search REST queries. |
timeZoneId | int | -1 |
Base url for GET request is the following:
{siteUrl}/_api/search/query
As you can see there are 45 parameters which we can use to get relevant search results. Therefore it's easy to run into bad request error.
So lets dive into SharePoint Search REST API POST request.
Base url for POST request is the following:
{siteUrl}/_api/search/postquery
In my samples I'll use jQuery to perform search queries and show results on a page.
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.5/angular.min.js"></script>
First of all here is a simple search POST request in SharePoint:
// SharePoint Search Query
var searchQuery = {
request: {
Querytext: "*"
}
};
// Request Body
var postQuery = {
/* static part of the query*/
method: 'POST',
url: "/_api/search/postquery",
headers: {
"Accept": "application/json",
"Content-Type": "application/json",
"X-RequestDigest": $("#__REQUESTDIGEST").val()
},
/* /static part of the query*/
// search query
data: JSON.stringify(searchQuery)
};
// jQuery AJAX
$.ajax(postQuery).done((response) => {
console.log(response);
});
Response for first query:
RelevantResults contains Table. Table contains array of Row. Each Row contains array of Cell. At last, Cell contains values:
The same response we could get for GET request. The only difference is the http method (GET, POST) we performed.
Selected properties must be passed as array of string:
var searchQuery = {
request: {
Querytext: "*",
SelectProperties: [
"Title", "ListID", "ListItemID", "Author"
]
}
};
There are two parameters which can be used for paging: StartRow (0 by default) and RowLimit (10 by default):
var searchQuery = {
request: {
Querytext: "*",
StartRow: 10,
RowLimit: 100
}
};
In search request you can set scope in which you need find out data. Built-in search scope listed in the following table:
Name | Id |
---|---|
Conversations | 459dd1b7-216f-4386-9709-287d5d22f568 |
Documents | e7ec8cee-ded8-43c9-beb5-436b54b31e84 |
Items related to current user | 48fec42e-4a92-48ce-8363-c2703a40e67d |
Local People Results | b09a7990-05ea-4af9-81ef-edfab16c4e31 |
Local Reports And Data Results | 203fba36-2763-4060-9931-911ac8c0583b |
Local SharePoint Results | 8413cd39-2156-4e00-b54d-11efd9abdb89 |
Local Video Results | 78b793ce-7956-4669-aa3b-451fc5defebf |
Pages | 5e34578e-4d08-4edc-8bf3-002acf3cdbcc |
Pictures | 38403c8c-3975-41a8-826e-717f2d41568a |
Popular | 97c71db1-58ce-4891-8b64-585bc2326c12 |
Recently changed items | ba63bbae-fa9c-42c0-b027-9a878f16557c |
Recommended Items | ec675252-14fa-4fbe-84dd-8d098ed74181 |
Wiki | 9479bf85-e257-4318-b5a8-81a180f5faa1 |
Source in SharePoint Search is actually predefined search query transform. For example Picture scope has the following one (filter by ContentTypeId):
{?path:{Scope}} {?owstaxIdMetadataAllTagsInfo:{Tag}} (ContentTypeId:0x0101009148F5A04DDD49cbA7127AADA5FB792B00AADE34325A8B49cdA8BB4DB53328F214* OR ContentTypeId:0x010102*)
Query with declared SourceId:
var searchQuery = {
request: {
SourceId: "9479bf85-e257-4318-b5a8-81a180f5faa1"
}
};
Simple string which contains comma separated refiners
var searchQuery = {
request: {
Refiners: "DisplayAuthor,FileType"
}
};
Refiner filter passed by array of FQL filters
var searchQuery = {
request: {
RefinementFilters: [
'DisplayAuthor:"Vitaly Zhukov"',
'FileType:or("docx", "xlsx")'
]
}
};
To simplify using the search result here is a very short javascript function:
// jQuery AJAX
$.ajax(postQuery).done((response) => {
console.log(response);
// result array of objects
var results = [];
response.PrimaryQueryResult.RelevantResults.Table.Rows.forEach(function (row) {
// result object
var item = {};
row.Cells.forEach(function (cell) {
// cell.Key = property name for result object
item[cell.Key] = {
Value: cell.Value,
ValueType: cell.ValueType
};
})
// add result object to result array
results.push(item);
});
console.log(results);
});
And now we have array of objects instead of array of arrays: