SharePoint 2013 - Manage Search Query Rule using Powershell

Following the Search Application Provisioning and Search Result Source configuration post, this post outlines how to configure Search Query rules in the SharePoint 2013.

Summary:

  • Initialize and get an instance of the Search Service Application
  • Update the existing Search Result Source (Site collection level)
  • Create a new Search Query rule
  • Set the rule condition and bind it to the Search Result source
  • Set the Query condition action to sort by "FileName" in descending order.
  • Search Results

Assumption:

Initialize and get an instance of the Search Service Application

$snapin = Get-PSSnapin | Where-Object {$_.Name -eq 'Microsoft.SharePoint.Powershell'}
if ($snapin -eq $null) {
       Write-Host "Loading SharePoint Powershell Snapin"
       Add-PSSnapin "Microsoft.SharePoint.Powershell"
}

$SearchServiceApplicationName = "Search Application"
$SiteUrl = "http://win-2j3idcdeuh6/"
$RootSiteCollection = Get-SPSite $SiteUrl -ErrorAction SilentlyContinue

#-----------------------------------------------------
# Get the Search Service application
#-----------------------------------------------------
$SearchServiceApplication = Get-SPEnterpriseSearchServiceApplication -Identity $SearchServiceApplicationName -ErrorAction SilentlyContinue
$FederationManager = New-Object Microsoft.Office.Server.Search.Administration.Query.FederationManager($SearchServiceApplication)

Update the existing Search Result Source

Note: The below script sets the existing Result Source to a default one and without any filters.



#--------------------------------------------------------------------------
# The below line creates a Search Object owner at the site collection level
# and this can be changed to Search Application or Site level by passing
# different SearchObjectLevel argument.
#--------------------------------------------------------------------------
$SearchOwner = New-Object Microsoft.Office.Server.Search.Administration.SearchObjectOwner –ArgumentList @([Microsoft.Office.Server.Search.Administration.SearchObjectLevel]::SPSite,$RootSiteCollection.RootWeb)

$ResultSourceName ="Test Result Source"
$Query = "{searchTerms} Title:*"
$ResultSource = $FederationManager.GetSourceByName($ResultSourceName,$SearchOwner)
if($ResultSource)
{
    #-----------------------------------------------------------
    # Update the existing query property.
    #-----------------------------------------------------------
    $ResultSource.CreateQueryTransform($queryProperties, $query)
    $ResultSource.Activate()
    $ResultSource.Commit()

    #-----------------------------------------------------------
    # Update the new Search source as a default one...
    #-----------------------------------------------------------
    $FederationManager.UpdateDefaultSource($ResultSource.Id,$SearchOwner)
}
else
{
    Write-Host "Result Source : $ResultSourceName does not exist".
}

Create a new Search Query rule

Note: The below script creates a new query rule for the search term "test"

#-------------------------------------------------------------------
# Configure a Query Rule to sort by Filename
#-------------------------------------------------------------------
$QueryRuleName = "Test - Sort by File name"
$QueryRuleConditionTerm = "test"
$QueryRuleManager = New-Object Microsoft.Office.Server.Search.Query.Rules.QueryRuleManager($SearchServiceApplication)

# Create a search object filter using a $SearchOwner object  (Site collection level - in this case)
$SearchObjectFilter =  New-Object Microsoft.Office.Server.Search.Administration.SearchObjectFilter($SearchOwner)
$QueryRules = $QueryRuleManager.GetQueryRules($SearchObjectFilter)
ForEach($Rule in $QueryRules)
{
    if($Rule.DisplayName -eq $QueryRuleName)
    {
        Write-Host "Query Rule : $QueryRuleName already exist. Deleting..."
        $QueryRules.RemoveQueryRule($Rule)
        break
    }
}

$QueryRules = $QueryRuleManager.GetQueryRules($SearchObjectFilter)

# Create a new rule as a active one.
$QueryRule = $QueryRules.CreateQueryRule($QueryRuleName,$null,$null,$true)

 

Set the rule condition and bind it to the Search Result source

# Set the Query Rule condition...
[string[]] $QueryRuleTerms = @($QueryRuleConditionTerm)
$QueryRuleConditions = $QueryRule.QueryConditions
$QueryRuleCondition = $QueryRuleConditions.CreateKeywordCondition($QueryRuleTerms,$true)

#Bind it to the Result Source...
$QuerySourceContextCondition = $QueryRule.CreateSourceContextCondition($ResultSource)

Set the Query condition to sort by "FileName" in descending order.

# Set the Query Condition action to change ranked results...
$QueryRuleAction = $QueryRule.CreateQueryAction([Microsoft.Office.Server.Search.Query.Rules.QueryActionType]::ChangeQuery)
$QueryRuleAction.QueryTransform.OverrideProperties = new-object Microsoft.Office.Server.Search.Query.Rules.QueryTransformProperties
$QueryRuleAction.QueryTransform.SourceId = $ResultSource.Id
 
# define a custom sorting - Order by FileName
$QueryRuleSortCollection = New-Object Microsoft.Office.Server.Search.Query.SortCollection
$QueryRuleSortCollection.Add("FileName", [Microsoft.Office.Server.Search.Query.SortDirection]::Descending)
 
$QueryRule.ChangeQueryAction.QueryTransform.OverrideProperties["SortList"] = [Microsoft.Office.Server.Search.Query.SortCollection]$QueryRuleSortCollection
$QueryRule.ChangeQueryAction.QueryTransform.QueryTemplate = "{searchTerms}"
 
$QueryRule.Update()

Search Results

Step1 : Go to the site (http://win-2j3idcdeuh6/) and search for "test". The search result brings all the test pages (testpage2.aspx and testpage1.aspx) in a descending order.

Step 2: Deactivate the rule and search for "test" in the search screen

Step 3: Search for "test" again and displays the results in the default order.

The full script can be downloaded from here SP2013%20-%20Manage%20Query%20rule.ps1

Views: 2878

Tags: Developer, IT-PRO

Comment by Kamal pandey on July 26, 2013 at 19:53

Good Post ...

Comment by Nelson Lamprecht on November 26, 2013 at 17:57

Thanks for the post; One thing I don't understand is how do I provision a result block through powershell or C#...Any ideas? Most of the data I have seen as part of the CreateQueryAction method on a QueryRule but the resultblockdata class seems to be internal...

Comment by Osmund Grov on December 20, 2013 at 22:19

Nelson: I have also tried to solve the result block mystery and it stopped with the sealed resultblockdata class for me as well. There is absolutely no documentation out there, really frustrating.  

Comment by Nelson Lamprecht on December 30, 2013 at 22:40

So, I finally figured it out and I had to make my own blog post about it:http://nelsonlamprecht.wordpress.com/2013/12/27/sharepoint-2013-sea....

Basically, copy the exiting result type into a new one using the contstructor for ResultItemType and then using the AddResultItemType method of a search proxy to add it to the connection...

Comment by Ronald Wierenga on February 4, 2014 at 20:58
Do you have a solution for my permisssion problem?

All users van see all documents but they dont have any permisssion.

http://sharepoint-community.net/forum/topics/search-security-proble...
Comment by Ramon torras on July 4, 2014 at 9:41

Great post!
Nelson:  I have seen your post also, super useful.  Both post show how we can do the same from c# or powershell.
Congratz men!

Ramon Torras
http://www.ramontorras.net

Add a Comment

You need to be a member of SharePoint Community to add comments!

Join SharePoint Community

© 2014   Created by Mark Jones.   Powered by

Badges  |  Report an Issue  |  Terms of Service

Live Support