Thursday 7 May 2015

SharePoint 2013 Custom Search - Part 2 - Result Sources and Query

This post follows directly on from my other post SharePoint 2013 Custom Search - Part 1 - Managed Properties which guides you through making your searched (crawled) data available to use in your solutions.
This post builds on this and uses this data in a meaningful way, pulling this into Search results by way of display templates - a new feature for displaying content in SharePoint 2013..

My end goal is to produce a search driven page that returns refine-able information about the way an IT project went, this information is captured in a retrospective meeting after the project has completed, the information captured is based around the 'feeling' e.g. positive, negative or warning.

The user experience i'm after is for a user to be able to search for a key word (or an asterisk * to search all content) and the same page display results showing custom information, with the ability to hover over these to provide further information.

The data for this is coming from a list, with columns that have been created, mapped and crawled following the principles outlined in my first post in this three-parter.






A list including crawled data, the next new thing to 2013 Search is the concept of a 'Result Source' this replaces the old 'scopes' from 2010. Head to Settings-Site Settings-Result Sources



You will see a list of Result Sources provided by SharePoint, take a look at these to familiarise yourself with the way they are created and the various ways these can be implemented.

To create a new result source, click (yes you guessed it) 'New Result Source'.
The purpose of this result source is to return results that only exist in a specific location - in this case the list above. So the settings we want here are:
Name: RestrospectiveLearning
Protocol: Local SharePoint
Type: SharePoint Search Results

Now for the query, hit 'Launch Query Builder'. Here we're stringing together three query parameters to get the right results.




?{searchTerms} - Is the internal variable for whats typed in the search box
Path:http://xxxx - Is the URL path of the results we're after
(contentclass:STS_ListItem) - Is the type of data we're looking to retrieve


Testing your query will return no results as there is no search term, so this is correct.

The next thing to do is create a page on which to add a search box and search results webpart, this will be the home for our users for this particular solution, they shouldn't need to navigate away from this page.



Here we have a plain old web part page and as you can see I've added a Search Box web part, Search Results web part and a Refinement web part (ok I've missed one, you can see a Script Editor web part here, I tell you what this does later, I promise!)

We need to link the Search Box and the Search Results web parts together so the results go to the right place! Simply edit the Search Box properties and tick the box that send results to the Search Results web part.



Now to configure the Search Results web part, so again edit the web part and choose 'Change query'




Next we see the query builder that SharePoint 2013 uses all over the place, this is similar to the one we used creating the result source.



This time we simply select the result source we created earlier. 

As for the refinement panel, edit the webpart and provided you have set the managed property (part 1 of this series) to 'Refinable' it will be available to select here, add the ones you wish to refine your results to 'Selected refiners'



Now for the elusive Reset Button you saw earlier. The reason this is included is I want results to appear for the users when they load the page. To achieve this, I need a wildcard (*) as a search term. I've added a script editor webpart and included the following javascript, firstly this changes the URL on page load to include the query '*' and secondly do the same thing when a button is pressed (labelled 'Reset').

<script type="text/javascript">
window.location =  '/sites/Retrospective-Learnings.aspx#k=*'
</script>
<div>
<input type="button" name="ResetBttn" title="Click to reset" style="margin-left: 0px;" onclick="location.href = '/sites/Retrospective-Learnings.aspx#k=*'" value="Reset">
</div>

Now to test.
Typing a term in the search box will now display desired results from the correct list in the search results web part. However, these are not styled as we would like as you can see..










Checkout SharePoint 2013 Custom Search - Part 3 - Display Templates for how to style this and bring it all together.

Wednesday 6 May 2015

SharePoint 2013 Custom Search - Part 1 - Managed Properties

This is the first in a three part blog which will focus on leveraging SharePoint 2013 Custom Search in a real world business solution, part one is creating managed properties, part two looks at getting these as part of result sources and querying, and finally part three brings it together with a bit of custom styling using display templates.

OK, so Microsoft have changed the way they have implemented Search in SharePoint 2013 - in quite a massive way if you didn't already know. 


Alongside some of the larger changes, there are a few smaller ones which aren't immediately obvious.

Once upon a time to configure managed properties, one had to venture into the 'Metadata Properties' section in 2010:



The game has changed a little, and this option is now embedded in 'Search Schema' in the 2013 world:


If you've already added managed properties in 2010 I hate to tell you how to suck eggs, but I'll cover it anyway as there are a few more changes, I'll point these out as we go on...

A few ground rules on managed properties and crawling -
Rule 1: You have to map a managed property to a crawled property

Rule 2: A crawled property is not a crawled property until its been crawled (kind of makes sense, but the next rule will clarify)

Rule 3: A crawled property is not registered as crawled unless there is some data against it

Rule 4: You have to run a full crawl before data in a crawl property is crawled

Hopefully that all makes sense, but basically, to add a managed property; create the column in SharePoint, add an item with data against that column, run a full crawl and the crawled property will be visible in central admin.

There will be a few of you reading this know your stuff that will be like 'hang on a minute, why do I need to map a crawled property to managed one in SharePoint 2013?'

Well the answer is - you dont! SharePoint 2013 has added a neat feature which creates a managed property automatically on a full crawl for any columns that contain data. However, I prefer to create mine manually for a few reasons.
Take the following two managed properties:


They both actually crawl the same value and will return the same thing, however the automatically created one (at the top of the screenshot above) you will see has a somewhat messy name appended with OWSTEXT. In addition, if you wanted this property to be searchable (which is extremely likely) you would have to edit the property as its created with only query and retrieve attributes.

So to create a managed property (after the rules above have been followed) choose 'Add New Managed Property' in the resulting screen give it a meaningful name (I would create this without spaces to make this easier to reference in javascript / html / xsl later):



Select the attributes that you wish this property to have:

Map this to a crawled property (you can map this to more than one crawled property!):



You are now able reference the values from crawled properties in your solutions using the managed property name. To read about how to achieve this as part of a business solution take a look at the second part in this series:




Tuesday 5 May 2015

New SharePoint 2013 Server Service - Distributed Cache

We recently installed our SharePoint 2013 server farm (and by recently, I mean around a year ago). I noticed a new server service that could be run in our farm called "Distributed Cache".


What is Distributed Cache?

Well, basically what it says on the tin, a caching functionality in SharePoint 2013. It is either required by or improves the folllowing features in SharePoint 2013:


  • Authenication
  • My Site Newsfeeds
  • Access for OneNote client
  • Security
  • Page loading performance
This service was not available in SharePoint 2010 like it is now in SharePoint 2013.

So when planning for this, you may want to consider using a dedicated Distributed Cache server or allocated memory to the Distributed Cache. The latter would affect performance however.

I have started the Distributed Cache server on our 2 Web Front End servers which are load balanced.

Planning for feeds and the Distributed Cache service can be found here:


Managing the service can be found here:


And a full overview of Distributed Cahce is here:

Unable to Modify View: /_vti_bin/owssvr.dll?CS=65001

So I received an email from one of my key stakeholder's a few days ago saying they were unable to modify a view as everytime they pressed OK on the Modify View page, there received a funny looking error:


ERROR:

The error below shows: _vti_bin/owssvr.dll?CS=65001 after the normal URL. Therefore something along the lines of: http://SharePointTest/_vti_bin/owssvr.dll?CS=65001



After searching through the logs and finding various Trace logs in my ULS viewer, there wasn't quite much there to resolve my issue.

Something to note here is however, that I do have Server Publishing Feature activated.

RESOLUTION:

I searched a bunch of articles online and eventually found one mentioning about something called "Minimal Download Strategy" or MDS feature. On my site features, I happened to have this activated. I believe that is doesn't really work with items such as the Publishing Portal, Enterprise WIKI and Project Web App.



I de-activated this feature and suddenly, I was able to modify views and no error appears anymore.

This is a new feature in SharePoint 2013 and is automatically activated on Team Sites. This feature reloads parts of a page that have changed. When modifying the view, the whole page has changed and for some reason, throws up this error.