Showing posts with label Refiners. Show all posts
Showing posts with label Refiners. Show all posts

Wednesday, August 9, 2017

Sharepoint search refiners and powershell

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,","")











Sort Refiner Values Alphabatically Sharepoint Search 2013

If you are using Managed Metadata Terms as a search refiners then you have noticed that your Refiners values are not coming on alphabetically sorted.

Let's take an example for the same

If you have created a Site Column eg. Term1 Type Managed Metadata Column

Associate this column "Term1" with a List
Add some items to the list and tag the Term1 to some Managed Metadata Terms

Run the Full Crawl from Search Service application

Go to Search Schema in Search Service application and search for Crawled Property





in the Search Box type Term1. After search you will get 2 Crawled Properties

  • ows_taxId_Term1
  • ows_Term1


  • ows_taxId_Term1 contins the TermID along with the TermSet display name. If you add this in your refiner and apply sorting on Name it will sort ASC or DESC based on the TermID

  • ows_Term1 contains the TermSet Display Name. If you cannot add this directly in your refiners because it's not a Managed Property. You need to create a managed property for this and Map this crawled property with your managed property.


Steps to Create a Managed Property

Click on "New Managed Property" in Search Schema Page
Name : Provide Some Name eg. MyTerm
Type : Text
Searchable : True
Queryable : True
Retrievable : True
Allow multiple values : True
Refinable : Yes Active
Sortable : Yes Active

In Add Mapping Screen Search for ows_Term1 and add it
Click on OK


Run the Full Crawl

Add your managed property as Refiner  and set the properties as below on the picture


Display Name : Term 1
Sort by : Name
Sort Direction : Ascending

you will get refiner values are appearing in a sorted order.