Manually adding Search Query Suggestions in SharePoint 2013 using PowerShell

One of the cool features that existed in SharePoint 2010 and has been further enhanced in SharePoint 2013 is Query Suggestions.

Query suggestions are suggested terms that appear in a list view below the Search box while the user is typing a query. Query suggestions are automatically generated for a query when users click a result for that same query at least 6 times. The clicked result does not need to be the same one, but can be any result that was returned for the query. Users’ clicks on results are logged and entry pairs of (query, result) are added to the Analytics Link Store DB, specifically to the MSSQLogPageClick table.

Then on a daily basis, the SharePoint timer job titled “Prepare Query Suggestions” fires off to analyze and process the logged queries and clicks to prepare query suggestions.


The default OOTB behavior for generating query suggestions depends on users' actually performing searches in the Search Center and clicking on documents. For new deployments of SharePoint, this would mean that we are going to start clean and it might take a while until query suggestions start showing up for us. Enterprises have a wide set of domain specific terms that would be very useful to be used as a seeding collection for query suggestions, or simply query phrases that are considered so important that should always be suggested to users regardless of being searched for previously by other users. Also, in upgrades, we already have a bunch of terms from query logs that we want to use in the new SharePoint 2013 solution.

So, how can we manually add query suggestions in SharePoint 2013? One way is to import a text file populated with our suggestions using the Query Suggestion Settings page under Central Admin -> Search Service Application. The procedure for using this page is described stepwise on this page on TechNet.


To automate the procedure of adding Query suggestions, we’re going to use PowerShell. There are actually two ways to do this:


1. Using the Import-SPEnterpriseSearchPopularQueries cmdlet

This allows you to import a text file containing your query suggestions and has basically the same effect as using the Query Suggestion Settings Admin page in Central Admin.

Looking more closely at this cmdlet, we investigate the following two parameters of special interest.


ResultSource: This is a pointer to a Search Result Source where your suggestions will show up to users. As an example, if you specify “Local SharePoint Results” as the result source, suggestions will only show up when searching in the context of that result source.

Web: This is the SPWeb were your suggestions will be scoped at. Say you specify the Web of your Enterprise Search Center here, suggestions will only show up when in context of that web, sub web sites or other web sites within the same site collection will not automatically inherit query suggestions from the parent site.

The main difference between using this cmdlet and the Query Suggestion Settings page for importing a text file with Query suggestions, is that suggestions uploaded using the Query Suggestion Settings page will always be scoped at a Search Service Application level, meaning that suggestions will be listed for users across all site collections and web sites using the same Search Service Application. While if using the cmdlet, you must specify a Web as the scope.


Ok, let’s look at how the Import-SPEnterpriseSearchPopularQueries cmdlet can be used.


 $ssap = Get-SPEnterpriseSearchServiceApplicationProxy
 $web = Get-SPWeb -Identity http://hostname/[site]
 $owner = Get-SPEnterpriseSearchOwner -Level SPWeb -SPWeb $web
 $manager = New-Object Microsoft.Office.Server.Search.Administration.Query.FederationManager –ArgumentList $ssap
 $source = $manager.GetSourceByName("Local SharePoint Results", $owner)
 Import-SPEnterpriseSearchPopularQueries -SearchApplicationProxy $ssap -Filename C:\query-suggestions.txt -ResultSource $source -Web $web
 $tj = Get-SPTimerJob -type "Microsoft.Office.Server.Search.Administration.PrepareQuerySuggestionsJobDefinition"


My query-suggestions.txt file looks like this:

Windows 8,10,70,1033
Enterprise Search,90,50,1033


Where each line consists has this format:

[Query Suggestion Terms,Query Count,Click Count,LCID]


2. Using the New-SPEnterpriseSearchLanguageResourcePhrase cmdlet

This allows you to add a single language resource entry at a time.

The types of language resource phrases available are:

- QuerySuggestionBlockList – a query suggestion entry that will be blocked from showing up. For example secret codes, offensive words, etc…

- QuerySuggestionAlwaysSuggest – a query suggestion that will always be shown. Ie. it is not personal to specific user.

- Nickname – Used for mapping synonyms for people names.

- QuerySuggestionSubstitution – Used for mapping terms. For example, if the phrase is “car”, you can add a mapping to “car or auto”. The phrase “car” will show up as the suggestion, but when the user selects that suggestion, the actual query will be “car or auto”.

 Looking at theavailable parameters on this cmdlet, we notice the following two parameters which grab attention:

Owner: Specifies the scope at which the corresponding language resource phrase is created.

The available scopes are: SPWeb, SPSite, SPSite Subscription and SSA.

 SourceId: Specifies the Id of the Search Result Source where the language resource pharse will be applied to. This is an optional parameter, so if this is not provided when running the cmdlet, the language resource phrase will be applied to all result sources.


The difference between the two cmdlets, is that the second one does not require an SPWeb as a parameter, hence you can create Query suggestions that can be scoped at different levels. You can scope a suggestion to a site collection, web site or Search Service Application.


Following, we look at some example runs of the New-SPEnterpriseSearchLanguageResourcePhrase cmdlet.

Adding a query suggestion at the SiteCollection level, will allow the query suggestion phrase to show up under all Webs within the site collection.

If we don’t specify the SourceId parameter, the suggestions will be applied to all result sources and show up when searching under any of the verticals in the Enterprise Search Center.


 $spsite = Get-SPSite -Identity http://hostname
 $ssa = Get-SPEnterpriseSearchServiceApplication
 $owner = Get-SPEnterpriseSearchOwner -Level SPSite -SPWeb $spsite.RootWeb
 New-SPEnterpriseSearchLanguageResourcePhrase -Name "suggest me" -SearchApplication $ssa -Type QuerySuggestionAlwaysSuggest -Language "en-us" -Owner $owner
 $tj = Get-SPTimerJob -type "Microsoft.Office.Server.Search.Administration.PrepareQuerySuggestionsJobDefinition"


Adding a query suggestion at a Web site level, will restrict the suggestion phrase to show up only under the specified web site.


 $spweb = Get-SPWeb -Identity http://hostname
 $ssa = Get-SPEnterpriseSearchServiceApplication
 $owner = Get-SPEnterpriseSearchOwner -Level SPWeb -SPWeb $spweb
 New-SPEnterpriseSearchLanguageResourcePhrase -Name "suggest me" -SearchApplication $ssa -Type QuerySuggestionAlwaysSuggest -Language "en-us" -Owner $owner
 $tj = Get-SPTimerJob -type "Microsoft.Office.Server.Search.Administration.PrepareQuerySuggestionsJobDefinition"


 In a future post, we’ll see how suggestions are being fetched from the UI, and look at using the Search REST API to retrieve query suggestions.