Friday, October 31, 2014

Caution: If you have scripted your Search Service Application (eg. AutoSPInstaller) in SharePoint 2013 your search based pages could end up like this

Important!
If you have scripted your SSA, make sure the farm account has db_owner on your search db’s, or you may find yourself in a lot of trouble one day!

search-based-intranet

Wednesday, October 29, 2014

Retrieve Search Center URL from a SharePoint page

I have previously written about how you via REST can retrieve the Search Center URL for a particular SharePoint site.

If you are already on a page which has a search web part on it, you can get the same value from the page itself with the following command:

Srch.ScriptApplicationManager.get_current().states['searchCenterUrl']


To be clear; when a search web part exist on the page search Search.ClientControls.js is loaded and makes the Srch namespace available.

Tuesday, October 28, 2014

How to change the number of decimal places on a number column using CSOM

Got a challenge for a one liner by the strongest man in SharePoint (@tarjeieo) to do this using CSOM as with with SSOM you can set the DisplayFormat property of the field. Using CSOM, this property is not available.

A one liner would be ugly, but the way to accomplish this is to modify the SchemaXml of the field, so you could encapsulate the code below in a function.

Using XML manipulation I ended up with this.

ClientContext clientContext = new ClientContext("https://site/);
Web web = clientContext.Web;
Field field = web.Fields.GetByTitle("DummyNum"); // Field to modify
clientContext.Load(field);
clientContext.ExecuteQuery();
XmlDocument doc = new XmlDocument();
doc.LoadXml(field.SchemaXml);
XmlNode fieldNode = doc.SelectSingleNode("Field");
XmlAttribute decimalAttribute = fieldNode.Attributes["Decimals"];
if (decimalAttribute == null)
{
decimalAttribute = doc.CreateAttribute("Decimals");
fieldNode.Attributes.Append(decimalAttribute);
}
decimalAttribute.Value = "4";
field.SchemaXml = doc.OuterXml;
field.UpdateAndPushChanges(true);
clientContext.ExecuteQuery();

Monday, October 27, 2014

Caution when creating global query rules

If you create query rules which modify the query on your tenant or SSA level, then you are effectively killing off any such rules on the site collection level.

The below screen shot is taken running a query in the query rule tester. You see the first rule for blog’s is triggered. This rule has been set to stop, as it modifies the query and I want no more processing. You can see the stop flag actually works works, as the next rule is grayed out.

But then a rule from the SSA is showing in blue again, not honoring the Stop flag from the site collection. Ideally it should have been grayed out as well. The reason for this is that if you have more than one rule which modifies your query, then neither is executed (even though the test interface shows so).

image

In my case the SSA rule is adding an exclusion rule for all search results on Local SharePoint Results. The way to solve this is to create a custom result source on the SSA (or any other level where you need it), add the exclude filter here, and set this source as the default source instead.

Or if the results excluded shouldn’t be used anywhere, mark the site not to be indexed instead.

Tuesday, October 21, 2014

I'm doing an extra talk at SharePoint Connect 2014 - Social Refiners is the game!

Back in May I posted about SharePoint Connect 2014 letting me in to do a talk about Search Queries Explained. A vacant spot just opened up and I was asked if I could do one more, and I jumped at the chance.

I've decided to do a developer talk on how to create "Social" refiners on your search result pages.

The session will involve Display Templates and JavaScript with some FQL sprinkled in. I will show how to create my trusty old Department refiner for content and a refiner for content close to you, both based on your organization, who you follow and who you interact with from the Office Graph.

Hopefully you will pick up a trick or two and get some ideas for your next project - and if you are near sighted, sit up front as it's all code :)

Monday, October 20, 2014

Look up item based on the Item’s ID

If you kick off a search query you get some default properties with a document. One of these are DocId.

image

The managed property DocId is of type text and marked as searchable, and you would assume you a search like DocId=123456 will bring back a result back.

image

For some reason this does not work. The workaround however is easy.

There exists a managed property called WorkId which is also returned per result, but it’s not visible in the search schema. This property is of type integer with the same value as DocId and you can bring back one item with the following query:

WorkId:123456 or WorkId=123456

You can also do WorkId<>123456 or -WorkId:123456 if you want all items except one item in particular.

Alternatively you can map the crawled property ows__dlc_DocId to a managed property of your choice and use that instead, but no reason to do that since another solution exists.

Friday, October 17, 2014

Using search to redirect a user to the correct home site

image
I was recently tasked with the following challenge.

Given a two-level site structure of Region and Country, a user should be redirected to the corresponding site to where he/she works. This means if you work in Norway you should be redirected to http://intranet/About/Europe/Norway. If you work in Germany, which doesn’t have a country site of it’s own, you should be redirected to the region site at http://intranet/About/Europe.
  • About
    • Europe
      • Norway
      • Sweden
      • Denmark
    • APAC
      • China
      • India
      • Japan
    • Central Office
The URL structure of the sites replicate the taxonomy used for settings the values in Active Directory which is synchronized to the User Profile Application.

Thursday, October 16, 2014

Retrieving and working with Search Navigation entries using CSOM

I’m currently working on some provisioning tasks for a search page and we want to script up the search navigation using CSOM. This would be the Everything, People, and Social tabs you see below the search box.
The issue is that Web.Navigation does not have the SearchNav property which SPWeb.Navigation has. It only has QuickLaunch and TopNavigationBar.
But just because the good guys over at Microsoft haven’t gotten around to implement all the SSOM properties doesn’t mean we’re stuck. Using Reflector I figured out the node id for the search navigation was 0x410. Which yields the following code.
string siteUrl = "http://dev/sites/search";

ClientContext clientContext = new ClientContext(siteUrl);
Web web = clientContext.Web;

var nav = web.Navigation;

NavigationNode searchNav = nav.GetNodeById(1040);
NavigationNodeCollection nodeCollection = searchNav.Children;

clientContext.Load(nodeCollection);
clientContext.ExecuteQuery();

foreach (NavigationNode navigationNode in nodeCollection)
{
    Console.WriteLine(navigationNode.Title + " : " + navigationNode.Url);
}

Take a look at http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.client.navigationnodecollection(v=office.15).aspx for sample code on how to add more nodes to the collection.

Enjoy!

Wednesday, October 15, 2014

S15E10: Search Orchestration - Page composition in rule major

This is episode ten in the series “SharePoint Search Queries Explained - The Series”. See the intro post for links to all episodes.

This post covers two main objectives. Firstly how to configure search for any page to make it manageable in the long run, and secondly how to configure search for that same page to make the page show as fast as possible to the end-user.

The main tool used to accomplish this is Result Block Routing in a Query Rule. If you haven’t read about it before, now is certainly the time.

image

How to: Quickly switch audio input in Lync 2013

image

When I move my computer around I tend to plug in and out different headsets, and Lync more often than not have the wrong one set as the default one. This results in that I a lot of times when on voice calls have to hang up, click the cogwheel icon, then Tools and Audio Device Settings, and pick the right audio device.

I’ve done this ever since Lync 2013 was released… up until today when I discovered a clever icon in the lower right corner of Lync. With two clicks I can now pick my Logitech headset – and hopefully remember to do it before a call starts.