Search This Blog

Tuesday, March 1, 2016

SharePoint 2013: How to apply refiners in search using REST services

In last post we had deep walk through in Search REST service response. In this post we will learn how to get refiners and their various refinement values and tokens.

To get the refiners along with search result construct  REST URL as follows:

URL/_api/search/query?querytext='yammer'&refiners='Write,DisplayAuthor,ContentType,FileExtension,FileType'

You can use parameter 'refiners' to provide the multiple refiners. In result you will get all refiner values and their tokens in response in RefinementResults section or tag as shown below.



We have seen 'RefinementResults' and 'Refiners' in detail in last post. Now let’s see how to use them and construct the custom filter component for the custom search component.
Each Refiner contains multiple refinements for filters. You can get the Refinement Name, Token and Value which is useful while making refinement on search results. So to get them you need to iterate them like below:

$.each(data.d.query.PrimaryQueryResult.RefinementResults.Refiners.results, function () { 
                          var items = new Array();
                          var title = this.Name;                         
                          $.each(this.Entries.results, function () {
                                    var refinementName = this.RefinementName;
                                    var refinementValue = this.RefinementValue;
                                    if(title == "ContentType" && refinementName.indexOf(" ") != -1)
                                    {
                                                refinementName = refinementName.substring(refinementName.lastIndexOf(" "));
                                                refinementValue = refinementName;           
                                    }
                                    if(title == "Write")
                                    {
                                                refinementValue = this.RefinementToken;
                                    }                                                                                  
                          });                  
      });

In this way you can get all refiners and bind on the page. Next important part remaining of this component is filtering search results on the basis of refiners. To refine the result you need to pass the refinement filters as shown in below example REST URL:

/_api/search/query?querytext='yammer'&refiners='Write,DisplayAuthor,ContentType,FileExtension,FileType'&refinementfilters=’ refinementfilter: refinementfilterValue’

Following is the complete code which demonstrates how to use the filters. 

HTML Code:

<script type="text/javascript" src="/Site%20Assets/js/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="/Site%20Assets/js/knockout.3.2.0.js"></script>
<script type="text/javascript" src="/Site%20Assets/js/FilterSearch.js"></script>
<div class="row">
<div class="col-xs-12 col-sm-4 col-md-4">

<div class="panel-group" id="accordion" role="tablist" aria-multiselectable="true" data-bind="foreach: Refiners">
  <div class="panel panel-default">
    <div class="panel-heading" role="tab" data-bind="attr: { id: HeadID }">
      <h4 class="panel-title">
        <a data-toggle="collapse" data-parent="#accordion" aria-expanded="true" data-bind="attr:{href: HRef, 'aria-controls': ID}">
          <span data-bind="text: Title"> Collapsible Group Item #1 </span>
        </a>
      </h4>
    </div>
    <div data-bind="attr: { id: ID, 'aria-labelledby': HeadID }" class="panel-collapse collapse in" role="tabpanel" >
      <div class="panel-body">

<div class="list-group" data-bind="foreach: RefinerItems">
     <a href="#" class="list-group-item"><span data-bind="text: RefinementName, click: RefinerFliterClick.bind(Title, RefinementValue)"></span></a>
</div>       

      </div>
    </div>
  </div>  
</div>
</div>
<div class="col-xs-12 col-sm-8 col-md-8">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-6">
<input type="text" class="form-control" placeholder="Search" id="txtSearch">
</div>
<div class="col-xs-12 col-sm-6 col-md-6">
<button type="button" class="btn btn-default" data-bind="click: btnSearchClick">Search</button>
</div>
</div>
<div class="row">
<div style="width:100%;padding-left:10px;" data-bind="foreach: Results">
<div class="row">
  <div class="col-xs-12 col-sm-12 col-md-12" style="border-bottom: 1px solid;padding-bottom:10px;">
<div style="width:100%">
<a href="" data-bind="attr: { href: Url }"><h4><span data-bind="text: Title"> </span></h4></a>
</div>
<div style="width:100%">
<p data-bind="html: HitHighlightedSummary"> </p>
</div>
<div style="width:100%">
<a href="" data-bind="attr: { href: Path }"><span data-bind="text: Path"> </span></a>
</div>
<div style="width:100%">
<span class="label label-default"> Author: <span data-bind="text: Author"> </span> </span>
</div>
  </div>
</div>
</div>
</div>
</div>

</div>

JS Code:

var RESTURL = "/_api/search/query?querytext=";
var DEFLTRFINERURL = "&refiners='Write,DisplayAuthor,ContentType,FileExtension,FileType'";
$(document).ready(function () {
    SearchModel();
});
function SearchModel()
{
 var self = this;
 self.Results = ko.observableArray([]);
 self.Refiners = ko.observableArray([]);
 self.Refiner = function(headID,id, title, items)
 {
 var self = this;
 self.HRef = "#" + id;
 self.HeadID = headID;
 self.ID = id;
 self.Title = title;
 self.RefinerItems = ko.observableArray(items);
 }
 self.RefinerItem = function(title, name, value)
 {
var self = this;
self.Title = title;
self.RefinementName = name;
self.RefinementValue = value;
 }
 self.SearchResult = function(url,title,hitHighlightedSummary,author,path)
 {
 var self = this; 
 self.Url = url;
 self.Title = title;
 self.HitHighlightedSummary = hitHighlightedSummary;
 self.Author = author;
 self.Path = path;
 }
 self.RefinerFliterClick = function(refinerName,refinerfiltervalue)
 {
var url = RESTURL + "'" + $("#txtSearch").val() + "'"; 
var RFINERURL = "&refiners='" + refinerfiltervalue.Title + "'";

if(refinerfiltervalue.Title.toLowerCase() == "write")
{
RFINERURL = RFINERURL + "&refinementfilters='" + refinerfiltervalue.Title.toLowerCase() + ":" + refinerfiltervalue.RefinementValue + "'";
}
else{
RFINERURL = RFINERURL + "&refinementfilters='" + refinerfiltervalue.Title.toLowerCase() + ":equals(\"" + refinerfiltervalue.RefinementValue + "\")'";
}
self.SearchInSharePoint(url + RFINERURL);
 }
 self.btnSearchClick = function()
 { 
var url = RESTURL + "'" + $("#txtSearch").val() + "'" + DEFLTRFINERURL; 
self.SearchInSharePoint(url);
 }
 self.SearchInSharePoint = function(url)
 {
 self.Results.removeAll();
 self.Refiners.removeAll();
 $.ajax({
 url: url,
 type: "GET",
 headers: {
 "accept": "application/json;odata=verbose",
 },
 success: function (data) {

 $.each(data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results, function () {
  self.Results.push(new self.SearchResult(this.Cells.results[6].Value,this.Cells.results[3].Value,this.Cells.results[11].Value,this.Cells.results[4].Value,this.Cells.results[6].Value));
  i++;
 });

 if(data.d.query.PrimaryQueryResult.RefinementResults != null)
 {
 var i =1;
 $.each(data.d.query.PrimaryQueryResult.RefinementResults.Refiners.results, function () {
  
  var items = new Array();
  var title = this.Name;   
  $.each(this.Entries.results, function () {
var refinementName = this.RefinementName;
var refinementValue = this.RefinementValue;
if(title == "ContentType" && refinementName.indexOf(" ") != -1)
{
refinementName = refinementName.substring(refinementName.lastIndexOf(" "));
refinementValue = refinementName;
}
if(title == "Write")
{
refinementValue = this.RefinementToken;
}

items.push(new self.RefinerItem(title, refinementName,refinementValue));
  });

  self.Refiners.push(new self.Refiner("HeadID" + i,"Collapse" + i,this.Name,items));
  i++;
 });
 i = 1;
}
 },
 error: function (error) {  
 alert(JSON.stringify(error));
 }
 });
}
ko.applyBindings(self);
}

Note: Knock out JS framework has been used while implementation. In order to run this code you need to refer knock out js file.

No comments:

Post a Comment