Most important innovation in search during the past years, has been the use of metadata-driven faceted search, to help users customise search results, one click at a time.
In SharePoint 2013, these search navigation options are referred to as search refiners.
Refiners are an extremely important part of the enterprise search experience.
SharePoint search refiners are metadata-driven.
If we open up our Search Centre and query on some data, down the left hand side of the search results is a search refinement panel. This panel gives a breakdown of some metadata found within the search results which allows you to filter it further.
If you look at the default search refiners, You will get refiners Result Type, Site, Author, Modified Date, and Location.
To get the search to work, you first need to ensure you have put data in a list with the columns you wish to search on, and perform a crawl in Central Administration for any results to show up in search. There are two different types of Search Refiners you can create ManagedPropertyFilterGenerator, or a TaxonomyFilterGenerator.
Here i am taking example of a TaxonomyFilterGenerator Refiners
We can add any custom refiners on the Result Page by Editing the page and editing the Refinement Webpart properties
In this blog we are talking about powershell script to do the same thing.
# Get our page and check it out
$spweb = Get-SPWeb "http://localhost/search/"
$page = $spweb.GetFile("Pages/results.aspx")
$page.CheckOut()
# Find the Refinement web part
$webPartManager = $spweb.GetLimitedWebPartManager("http://localhost/search/Pages/results.aspx", [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
$rwp = $webpartmanager.webparts | ? { $_.title -eq 'Refinement' }
# Refiners are Added/updated by changing the JSON
$j = $rwp.SelectedRefinementControlsJson | ConvertFrom-Json
$jsonString = @"
{
"sortBy" : 1,
"sortOrder" : 1,
"maxNumberRefinementOptions" : 15,
"propertyName" : "",
"type" : "Text",
"displayTemplate" : "~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_Default.js",
"displayName" : "",
"useDefaultDateIntervals" : false,
"aliases" : [],
"refinerSpecStringOverride" : "",
"intervals" : null
}
"@
# sortBy : 0-number, 1-Name, 2-Count; sortOrder : 0-Descending, 1-Ascending
# Adding new Refiner in Refinement Webpart
$newRefinerJson = ConvertFrom-Json $jsonString
$newRefinerJson.propertyName = "Your Managed Property Name"
$newRefinerJson.displayName = "Display Name you would like to set"
$j.refinerConfigurations += $newRefinerJson
$refJson = ConvertTo-Json $j -Depth 3 -Compress
$refJson = $refJson.Replace("null,","")
$rwp.SelectedRefinementControlsJson = $refJson
# Save our changes
$webpartmanager.SaveChanges($rwp) # save changes to webpart
$page.CheckIn('Added refiner')
$page.Publish('Added refiner')
The above script will add the new Refiner in the Refinement Webpart with the existing Refiners.
If you would like to remove all existing refiners and add the totally new set of Refiners then use the below Powershell script
Add-PSSnapin Microsoft.SharePoint.PowerShell -erroraction SilentlyContinue
# Get our page and check it out
$siteURL = Read-Host "Enter Search site Url"
$spweb = Get-SPWeb($siteURL)
try{
Write-Host -ForegroundColor Green "Processing start for : " $spweb.Title
$page = $spweb.GetFile("Pages/results.aspx")
$page.CheckOut()
Write-Host -ForegroundColor Green "Checking out Result page, Editing Refiners Webpart, Changing Refiners........."
# Find the Refinement web part
$webPartManager = $spweb.GetLimitedWebPartManager($spweb.Url + "/Pages/results.aspx", [System.Web.UI.WebControls.WebParts.PersonalizationScope]::Shared)
$rwp = $webpartmanager.webparts | ? { $_.title -eq 'Refinement' }
# Refiners are updated by changing the JSON
$refctljson = $rwp.SelectedRefinementControlsJson | ConvertFrom-Json
$refctljson.refinerConfigurations.Clear()
$jsonString = @"
{
"sortBy" : 1,
"sortOrder" : 1,
"maxNumberRefinementOptions" : 15,
"propertyName" : "",
"type" : "Text",
"displayTemplate" : "~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_Default.js",
"displayName" : "",
"useDefaultDateIntervals" : false,
"aliases" : [],
"refinerSpecStringOverride" : "",
"intervals" : null
}
"@
$newRefinerJson = ConvertFrom-Json $jsonString
$newRefinerJson.propertyName = "MPropertyDepartment"
$newRefinerJson.displayName = "Department"
$refctljson.refinerConfigurations += $newRefinerJson
Write-Host -ForegroundColor Green "Refiner 'Department' Added..."
$refJson = ConvertTo-Json $refctljson -Depth 3 -Compress
$refJson = $refJson.Replace("null,","")
$rwp.SelectedRefinementControlsJson = $refJson
# Save our changes
$webpartmanager.SaveChanges($rwp) # save changes to webpart
$page.CheckIn('refiner Added')
$page.Publish('refiner Added')
Write-Host -ForegroundColor Green "Refiner Changed and Page Checkedin for " $spweb.Title
}
catch
{
Write-Host Error occurred while Updating Refiners : $_.Exception.Message -ForegroundColor red
}
In this script only 2 lines are extra from the above script
$refctljson.refinerConfigurations.Clear()
This is to clear all the existing Refiners from the refinement webpart.
once the refiners are removed from the Refinement webpart then in JSON you will get null values for those refiners. And the PS is executed it throws error "Exception setting "SelectedRefinementControlsJson": "Object reference not set to an instance of an object.""
And your JSON would be like below
{"refinerConfigurations":[null,null,null,null,null,null,null,null,null,null,{"sortBy":1,"sortOrder":1,"maxNumberRefinementOptions":15,"propertyName":"MPropertyDepartment","type":"Text",
"displayTemplate":"~sitecollection/_catalogs/masterpage/Display Templates/Filters/Filter_Default.js","displayName":"Department","useDefaultDateIntervals":false,"aliases":[],"refine
rSpecStringOverride":"","intervals":null}]}
To fix this issue we need replace all the null values with blank to get rid of this error.
This line does the same
$refJson = $refJson.Replace("null,","")