The Property Bag is a “store” within SharePoint which can be used to places information’s and metadata. Property Bag is a hierarchical structure starting at farm level and goes down up to list level. Microsoft itself uses the Property Bag to store configuration settings and information’s. For details see that msdn article: Managing SharePoint Configuration
For common information’s about the Property Bag please refer that msdn sites:
The question is what benefit provides the Property Bag to us also in the context of search. In common we can use it to store variables or other metadata who belong to a site or list. Creating searchable properties in the property bag of a web, a site or a list allows us to search for them by the value of its property. Using that makes it easy to build search driven sites aggregating special subsides or list based on the value of such a searchable property. In case you work with custom website templates you can place a property in the Property Bag showing the type of your custom template. On the other side you can use search to say: ”Show me all sites where type is %whatever%”
We have several options to work with the Property Bag. In fact we can use SharePoint Designer, PowerShell and of course custom code. In addition there is a codeplex project named SharePoint Property Bag Settings. It is providing a farm solution to work with the Property Bag using the SharePoint UI. Poorly not all options give us the same potential.
Creating your own value in a Property Bag can be done with all options. But to create a property that is covered by search we have to respect some special things. For example creating a property in a Property Bag using PowerShell would work like this:
$WebUrl = "http://%Server%/sites/ "
$web = Get-SPWeb $WebUrl
$web.Properties ["MyNewProperty"] = "MyValue1"
But to make the property covered by search we need to do the following steps:
$web.AllProperties["MyNewProperty"] = „MyValue1"
Doing this using custom code it would look like that:
SPWeb web = SPContext.Current.Web;
web.AllowUnsafeUpdates = true;
web.AllProperties[“MyNewProperty”] = "MyValue1";
web.AllowUnsafeUpdates = false;
Poorly this cannot be done using CSOM. IndexedPropertyKeys are not part of the ClientObjectModel and also not available via REST. Thanks to my MVP colleague and company associate Thorsten Hans for supporting me with this question.
There is also no way to set this up using SharePoint Designer or the codeplex solution SharePoint Property Bag Settings. SharePoint Designer and the codeplex solution are helpful to see which properties already exist, to see which value they have or to change values.
This screenshot shows the Property Bag using SharePoint Designer. By clicking the button “Site Options” in the Ribbon, the shown dialog comes up. In the dialog you can see a custom property I created called “PowerShellProp”:
This screenshot shows the same information using the codeplex solution:
To get a list of properties from a Property Bag we can also use PowerShell.
$WebUrl.Properties | Format-List
To get a list of all properties covered by the search we need to use that call:
$WebUrl.IndexedPropertyKeys | Format-List
Before we can use the new property within the search we need to do a full crawl. After the full crawl we had a new Crawled Property named like our Property we created in the Property Bag in our search schema. To verify that the new crawled property exists we had to browse the search schema as described in respective msdn article: View crawled properties and managed properties
To use that property in search queries, search driven solutions or as a search refiner we need to map it to a Managed Property. Therefore we can use an already existing Managed Property or create a new one. How to do that mapping is described in following msdn article: map a crawled property to a managed property
After another full crawl the property can be used within search.
A hand on lab demo is shown in that video:
About the author
Nicki Borell (http://www.sharepointtalk.net/) is an evangelist & consultant in the Experts Inside team (www.expertsinside.com). He has worked for more than 13 years in Microsoft enterprise environments and also as a trainer and consultant for the SharePoint and SQL Server products. His expertise extends from technical consulting all the way to project management, with his core competencies covering KMU, enterprise environments and government data management. His special focus is on SharePoint Search Technologies. Nicki is Microsoft MVP for SharePoint, Microsoft Certified System Engineer (MCSE), Database Administrator (MCBA), IT Professional (MCITP) and Trainer (MCT). Follow him on Twitter.
About MVP Monday
The MVP Monday Series is created by Melissa Travers. In this series we work to provide readers with a guest post from an MVP every Monday. Melissa is a Community Program Manager, formerly known as MVP Lead, for Messaging and Collaboration (Exchange, Lync, Office 365 and SharePoint) and Microsoft Dynamics in the US. She began her career at Microsoft as an Exchange Support Engineer and has been working with the technical community in some capacity for almost a decade. In her spare time she enjoys going to the gym, shopping for handbags, watching period and fantasy dramas, and spending time with her children and miniature Dachshund. Melissa lives in North Carolina and works out of the Microsoft Charlotte office.
Vesa shows how this is done using CSOM in his blog post from Oct - blogs.msdn.com/.../ftc-to-cam-setting-indexed-property-bag-keys-using-csom.aspx
Great work Nicki !
Thanks for sharing the benefits of the Property Bag and lab demo.
While you might be right that 'IndexedPropertyKeys' is not available via CSOM/REST it should be noted that the properties are definitely accessible via CSOM/REST:
- http://site/_api/web/AllProperties (for REST)
- clientContext.get_web().get_allProperties(); (for ECMA CSOM)
Property bags just became so much more useful.
First of all thanks for an excellent write-up on this feature, and it will surely help many :) I know using the property bag is an easy way to store data, and having it searchable is all good. But from my experience it is much more maintainable to roll out a "MetaData" custom list on the site root with one single row of information, and index that instead for site metadata. Keep it as part of the site templates and populate it during site provisioning. And the good part, it's super easy to change afterwards as we can just edit the list item. Queries are also easy as crawled and managed properties are automatically created for us, and no need to run PowerShell/code to get it working.
I always love to get the super good use cases for functionality, and would love to get some insight in where I should use this over a list (besides sites already using the propertybag in legacy code).
Thanks for the write up, I was able to get this to work on one site but not another. Here is what I did Hopefully you can point me in the right direction.
Site Collection = /IT Used Team Site Template
Subsite1 = /it/ops Used Team Site Template
Subsite2 = it/itnews used blog.
New Site Collection = /Itprojects
I used the codeplex tool PropertyBagSettings2013
Created a Property on each of the sites called CH2M_Nav and gave each one a value of IT_Site
Then I ran a full Crawl.
Went into Search Schema, managed Properties, Created a new one called CH2MNav and mapped it to CH2M_Nav.
Reran Full Crawl.
Went to /IT site, put a Search Content web part on the page and the query I am using is CH2MNav:IT_Site
This returns 2 sites /it & /it/itnews I cannot get it/ops or /Itprojects to show up. in my results.
I have also downloaded and used "SharePoint 2013 Search Query Tool" and input the same query of CH2MNav:IT_Site and I get the same results. I am stumped as to why the two sites will not appear in the results. I have ran the following on both problem sites and I see CH2M_Nav listed.
$web = Get-SPWeb http://SERVERNAME/sites/IT/ops
Any Ideas as to why The two missing sites will not show up?
thx for you input. I think the main difference is that using a list mean finding the list items using the search. Using the property bag means finding the side or subside or list using the search
Check out the result by deactivating the “Hide Duplicates” function in the Querybuilder. Or by deselecting the “Trim Duplicates” checkbox in the QueryTool
The indexed property keys are available through CSOM via the 'vti_indexedpropertykeys' property of the web. Basically, this is a base64 encoded listing of the indexed property keys.
You can even add to it from CSOM as follows (this is CSOM in PowerShell, but should be enough to get a developer going):
$web = $ctx.Web
$indexedProperties = $web.AllProperties['vti_indexedpropertykeys'];
$bytes = [System.Text.Encoding]::Unicode.GetBytes("MyPropertyKey")
$encodedStr = [Convert]::ToBase64String($bytes)
$web.AllProperties['vti_indexedpropertykeys'] = $indexedProperties + $encodedStr + "|";
Can we use property of property bag as refiners (Refinable)?