Friday, March 9, 2012

How to: Make folder hits appear at the end of your search results

imagePaul Olenick tweeted me a question on how to get folder hits to appear at the end of the search results using FAST Search for SharePoint.

If we are talking about folders from file shares this is not too hard. If we refer to my post about Taking promotions/demotions one step further we can accomplish this by adding negative promotion using XRANK.

Firstly we need to identify folders which can be accomplished by using the IsDocument property, which for folders will be false.

Secondly we need to limit to file shares which can be accomplished by looking at the path property of the result, in this case it will start with file://.

XRANK takes at least three parameters, where the first one is the matching query, the second is the boost query and the last is the boost value. Using promotions the first part is made up by the users query, and the second is the FQL used to match folders on a file share as seen below.

To implement the demotion we’ll use PowerShell:
$searchSettingGroup = Get-FASTSearchSearchSettingGroup
$globalPromotions = $searchSettingGroup.PromotionsWithoutKeyword
$globalPromotion = $globalPromotions.AddPromotion("Demote folders") 
$globalPromotion.BoostValue = "-1000000"
$fql = 'and(isdocument:false,path:starts-with("file://"))'

For all queries the above fql will be added, demoting folders to the end of the result list. Other items may still appear below the folders if for example the freshness part (static boost) of the query pushes it above the folders. We can remedy this by giving a boost to all items which have IsDocument set to true.

$globalPromotion = $globalPromotions.AddPromotion("Promote non-folders") 
$globalPromotion.BoostValue = "5000"
$fql = 'isdocument:true'

Another approach may be to match all items with size = 0, and demote those instead.


  1. OK - Mikael, finally got a chance to implement the solution at the client. First of all thank you for posting this! I'll give you a huge shout out on my blog when I get around to talking about the final solution.

    I ended up going a slightly different route but mainly used what you posted here.

    Difference was I wanted to be able to pick and choose where this was used so I encapsulated it in a custom scope. This was what my final scope filter looked like:

    xrank(size:range(0,max), AND(isdocument:false, path:starts-with("file://")), boost=-1000000) AND xrank(size:range(0,max), isdocument:true, boost=5000)

    And,for anyone who needs it, this was the full powershell to create the scope:

    $mynewscope = New-SPEnterpriseSearchQueryScope -SearchApplication "FAST Query" -Name "FolderDemote" -Description "lower folders with xrank" -DisplayInAdminUI 1 -ExtendedSearchFilter'xrank(size:range(0,max), AND(isdocument:false, path:starts-with("file://")), boost=-1000000, boostall=yes)'

    Thank you again!!!

    1. Glad I could be of help :) And I understand the use of scopes when it's not a global adjustment. I also use the range(0,max) a lot for these catch-all scenarios.

      You can also tie this with Contextual scopes if you need it for certain people, so I think most scenarios are now covered regarding dynamic boosting with no code involved.