Friday, July 4, 2014

Mikael’s best practice for managing Managed Properties in SharePoint 2013/SPO–and how to deal with dates

I’ve had this on my mind for a while, but  Waldek Mastykarz post “Inconvenient Managed Properties and getting a list of all custom Managed Properties in SharePoint 2013” triggered me to share my thoughts.

To sum up Waldek’s posts, he shows a neat way to use PowerShell on-premises to filter out all non-system defined managed properties. The disadvantage is that the list will also include all managed properties auto generated from site columns. And you cannot use it for SharePoint Online.

One of the lacking points with the auto generated managed properties, is that they are of type text, even for date time values. If you want to filter on date ranges you need to use a managed property of type Date and Time which is sortable, and not a text property. As Waldek points out, the re-usable properties of RefinableDateXX are lacking as they return a string object and not a date object. They work for filtering, but in a Display Template they suck. This argument is used by Waldek to point out that you end up creating custom managed properties to deal with for example dates – and the argument is quite valid and not a bad one. Because Waldek is a pretty darn smart guy if you haven't noticed and his blog is certainly one to follow.

image

There is only way for 2010/SPO – My Way!

But to me the solutions is simple: I will never ever again create a new managed property (except for testing purposes), and will always use the re-usable properties. Yes, every single time! And you can quote me on it as well.

In 2010 I used to prefix my custom managed properties, but say you come back two years later tasked with moving or migrating the solution. You will have no idea who else has been touching the system in that time.

How on earth do you find all the managed properties you need to carry forward – unless there is really really good documentation available? And we all know that’s utopia right there.

If you put governance rules in place to only use the RefinableXXYY properties and also put aliases on them, you will in any context easily see which ones have been used. Your prefix is Refinable and the alias helps with usage. And for added benefit you have the option to use them at site collection levels as well, which is a good idea in my opinion as you don’t always need global managed properties.

image

What about the return value being String then? Well, that’s a minor inconvenience, and there are a couple of workarounds.
  1. Parse the value returned into a date object. This can be non trivial as in Norwegian it is returned as 04.07.2014 14:05:00 (dd.MM.yyyy HH:mm:ss), and for other locales it can be different.
  2. Be sure to always use site columns. This way you can use RefinableDateXX for sorting and filtering, and use columnNameOWSDATE in your UI, as the auto created managed property has date in the form of yyyy-MM-ddTHH:mm:ssZ, which is easily parsed into a unique date object. In JavaScript you could in a display template do something like:

    // 2014-07-04T14:05:00Z
    var dateString = ctx.CurrentItem.MyDateOWSDATE;
    var dateObject = new Date(dateString) 

    The thing is that when creating your UI you usually know what kind of data you are dealing with and can do the proper conversion if needed. It's usually one extra line, which is something I'm willing to compromise on and sticking to my RefinableXXYY guns.

Summary

My personal preference for managing managed properties is to always use the re-usable RefinableXXYY properties. Always try to use site columns and the auto-generated managed properties when possible.

If you need refinement or filtering, map your crawled properties accordingly, and use a combination of the RefinableXXYY property and the auto-generated siteColumnOWSTYPE property for UI experience at the potential cost of a one line conversion per managed property.