Thursday, May 30, 2013

SharePoint 2013 Search: Add an Index Component to a New Web Front End

I previously moved the query component to my single web front end server (WFE) and then moved the index partition . Now I have a second WFE provisioned and I wanted to create a query and an index component on that server as well. This post outlines the steps for the index component. The query component steps are here.


Get Search Service Instance and Start on New WFE Server
$ssi = Get-SPEnterpriseSearchServiceInstance -Identity "<<NEW WFE SERVER NAME>>"
Start-SPEnterpriseSearchServiceInstance -Identity $ssi

Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance -Identity "<<NEW WFE SERVER NAME>>"


Wait for Search Service Instance to come online
Get-SPEnterpriseSearchServiceInstance -Identity $ssi

In the full script I have a loop that waits for the service to become online.
 

Clone the Active Search Topology$ssa = Get-SPEnterpriseSearchServiceApplication
$active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa -Active
$clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone –SearchTopology $active



Create the New Index Component for Index Partition 0
New-SPEnterpriseSearchIndexComponent –SearchTopology $clone -SearchServiceInstance $ssi -IndexPartition 0             -RootDirectory "E:\SPIndex"

{click image to see larger view}

Activate  the Cloned Search Topology
Set-SPEnterpriseSearchTopology -Identity $clone

Optionally Review new topology
Get-SPEnterpriseSearchTopology -Active -SearchApplication $ssa

Monitor/Verify the Search Status
Get-SPEnterpriseSearchStatus -SearchApplication $ssa

In the full script I have a loop that waits for the index component to become active. The new Index Component will need to sync-up.

You may use the -text parameter to get additional information about the search component statuses:

Get-SPEnterpriseSearchStatus -SearchApplication $ssa -text


I now have the Index Partition across two web front ends:


{click image to see larger view}


FULL SCRIPT (with loops)
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Get Search Service Instance and Start on New WFE Server
$ssi = Get-SPEnterpriseSearchServiceInstance -Identity "<<NEW WFE SERVER NAME>>"
Start-SPEnterpriseSearchServiceInstance -Identity $ssi

Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance -Identity "<<NEW WFE SERVER NAME>>"

#Wait for Search Service Instance to come online
do {$online = Get-SPEnterpriseSearchServiceInstance -Identity $ssi; Write-Host "Waiting for service: " $online.Status}
until ($online.Status -eq "Online")


#Clone Active Search Topology
$ssa = Get-SPEnterpriseSearchServiceApplication
$active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa -Active
$clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone –SearchTopology $active


#Create New Index Component for Index Partition 0
New-SPEnterpriseSearchIndexComponent –SearchTopology $clone -SearchServiceInstance $ssi -IndexPartition 0 -RootDirectory "E:\SPIndex"

# Activate  Search Topology
Set-SPEnterpriseSearchTopology -Identity $clone


#Review new topology
Get-SPEnterpriseSearchTopology -Active -SearchApplication $ssa


#Monitor Distribution of Index
do {$activeState = Get-SPEnterpriseSearchStatus -SearchApplication $ssa | Where-Object {$_.Name -eq "IndexComponent2"}; Write-Host "Waiting for active distribution: " $activeState.State}
until ($activeState.State -eq "Active")

SharePoint 2013 Search: Add a Query Component to a New Web Front End

I previously moved the query component to my single web front end server (WFE) and then moved the index partition . Now I have a second WFE provisioned and I wanted to create a query and an index component on that server as well. This post outlines the steps for the query component. The index component was next and those steps are outlined here.


Get Search Service Instance and Start on New WFE Server
$ssi = Get-SPEnterpriseSearchServiceInstance -Identity "<<NEW WFE SERVER NAME>>"
Start-SPEnterpriseSearchServiceInstance -Identity $ssi

Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance -Identity "<<NEW WFE SERVER NAME>>"


Wait for Search Service Instance to come online
Get-SPEnterpriseSearchServiceInstance -Identity $ssi

In the full script I have a loop that waits for the service to become online.
 

Clone the Active Search Topology$ssa = Get-SPEnterpriseSearchServiceApplication
$active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa -Active
$clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone –SearchTopology $active





Add the New Query Processing Component
New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $clone -SearchServiceInstance $ssi


Activate  the Cloned Search Topology
Set-SPEnterpriseSearchTopology -Identity $clone

Optionally Review new topology
Get-SPEnterpriseSearchTopology -Active -SearchApplication $ssa

Monitor/Verify the Search Status
Get-SPEnterpriseSearchStatus -SearchApplication $ssa

In the full script I have a loop that waits for the index component to become active. If you have two index components, one usually needs to be re-synced.

You may use the -text parameter to get additional information about the search component statuses:

Get-SPEnterpriseSearchStatus -SearchApplication $ssa -text


I now have a Query Processing component on two web front ends:

{click image to see larger view}

Next I wanted to expand the index partition across the two WFEs and so I added a new Index Component to WFE2.


FULL SCRIPT (with loops)
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Get Search Service Instance and Start on New WFE Server
$ssi = Get-SPEnterpriseSearchServiceInstance -Identity "<<NEW WFE SERVER NAME>>"
Start-SPEnterpriseSearchServiceInstance -Identity $ssi

Start-SPEnterpriseSearchQueryAndSiteSettingsServiceInstance -Identity "<<NEW WFE SERVER NAME>>"

#Wait for Search Service Instance to come online
do {$online = Get-SPEnterpriseSearchServiceInstance -Identity $ssi; Write-Host "Waiting for service: " $online.Status}
until ($online.Status -eq "Online")


#Clone Active Search Topology
$ssa = Get-SPEnterpriseSearchServiceApplication
$active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa -Active
$clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone –SearchTopology $active


# Add New Search Component
New-SPEnterpriseSearchQueryProcessingComponent -SearchTopology $clone -SearchServiceInstance $ssi


# Activate  Search Topology
Set-SPEnterpriseSearchTopology -Identity $clone


#Review new topology
Get-SPEnterpriseSearchTopology -Active -SearchApplication $ssa


#Monitor Distribution of Index
do {$activeState = Get-SPEnterpriseSearchStatus -SearchApplication $ssa | Where-Object {$_.Name -eq "IndexComponent2"}; Write-Host "Waiting for active distribution: " $activeState.State}
until ($activeState.State -eq "Active")

Thursday, May 23, 2013

SharePoint 2013: Consistent Search Results with Synonyms and Query Rules

When I took a class called "Information Retrieval Systems" back in the 90's at Drexel University I never thought I would have to deal with what we learned directly. While the course covered things like stop words (noise words), lingusitics, synonyms, and basic retrieval of information, it really was the foundation for what search engines are built around today.

My professor's classic example was "Time Flies Like an Arrow" and "Fruit Flies Like an Apple". In the first phrase we want "flies" to be a verb but in the second phrase we want "flies" to be a plural noun. Also, "like" means similiar in the first phrase but means enjoys in the second. Hmmm...to a computer-based search engine they are words that will be searched against a content index and there really is no context around the meanings.

Same problem exists today when users want searches to produce the results they expect versus what the search engine actually finds and deems relevant. The specific problem I solved in SharePoint 2013 Search dealt with searching for "401K".

There are several ways someone may search for 401K ->  401K, 401 K, 401-K, and 401(K). Each of these phrases without any tinkering will produce a different set of results. I found that 401K and 401(K) produced the same number of results essentially because the parenthesis are ignored. So at least I had that covered.

The main problem is "401 K" because of the space. This produces results where there is just a 401 by itself or maybe a K by itself (as a middle initial for example). The "401-K" also produced different results as some content may actually contain the dash.

I originally thought this could all be solved just by using synonyms in my SharePoint 2013 Search thesaurus file (which you upload into Search using PowerShell). That was not the case. Then I thought I could solve the problem with a query rule - also not the case.

It turns out I needed to use a combination of thesaurus entries and a query rule to get the exact same number of results for any 401K combination. The ranking may change based on which version the user enters but as long as they get all of the possible results for each version we are making fruit fly.

Since 401K and 401(K) are treated the same, my thesaurus file contained the following:

Key,Synonym,Language
401 K,401K
401 K,401-K
401K,401 K
401K,401-K
401-K,401K
401-K,401 K

My condition for the query rule was based on if any version of 401K was entered:


The action for the query rules was to change the ranked results by changing the query:

 
 
Essentially I am using quotes to produce exact matches in the content which eliminates any extra results and, by combining with OR statements, I am assuring I get everything out there no matter how 401K is represented.
 
I really thought the query rule by itself would solve the problem but the synonyms helped seal the deal:
 
 
 
My SharePoint 2013 Search instance is now displaying the same number of results with each version of the search term.


 

SharePoint 2010/2013: Using PowerShell to Find Empty User Profile Properties

ADD THIS INFORMATION TO YOUR KINDLE LIBRARY!

Check out the whole SharePoint 2013 Solution Series
New Titles Added Weekly!

One of my readers, Mark Cole, needed some assistance on a PowerShell script. Together we crafted a quick solution to find all user profiles in SharePoint that did not have an entry for a specific property. Mark constructed most of the script and I put on some finishing touches.

Essentially we wanted to find all people that did not have a picture associated with their SharePoint User Profile. A user profile's picture information is stored in the PictureURL property. Therefore our example script finds all profiles that do not have an entry in PictureURL.

Here is what we did (full script at bottom of post):

First we needed some variables so we can easily modify the script for other properties or environments:

# Dynamic Settings
$mySiteUrl = "
http://mysite.company.net"
$findProperty = "PictureUrl"


Next, we needed to establish the server context:

# Obtain Context based on site
$mySiteHostSite = Get-SPSite $mySiteUrl
$mySiteHostWeb = $mySiteHostSite.OpenWeb()
$context = Get-SPServiceContext $mySiteHostSite



From the context we can instantiate a ProfileManager object and retrieve all of the SharePoint User Profiles:

# Obtain Profiles from the Profile Manager
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$AllProfiles = $profileManager.GetEnumerator()
$outputCollection = @()



Next, we loop through the profiles and retrieve the account name (for identification purposes) and the property we are interested in finding:

# Loop through profiles and retrieve the desired property
foreach ($profile in $AllProfiles)
{
    $output = New-Object System.Object
    $output | Add-Member -type NoteProperty -Name AccountName -Value $profile["AccountName"].ToString()
    $output | Add-Member -type NoteProperty -Name $findProperty -Value $profile[$findProperty]
    $outputCollection += $output
}


Finally, we list out the collection items that do not have a value for the property (ie. null):
# List all Accounts that do not contain the property
$outputCollection | Where-Object {[bool]$_.($findProperty) -ne $true}




FULL SCRIPT

# Dynamic Settings
$mySiteUrl = "http://mysite.company.net"
$findProperty = "PictureUrl"

Write-Host "Beginning Processing--`n"

# Obtain Context based on site
$mySiteHostSite = Get-SPSite $mySiteUrl
$mySiteHostWeb = $mySiteHostSite.OpenWeb()
$context = Get-SPServiceContext $mySiteHostSite

# Obtain Profiles from the Profile Manager
$profileManager = New-Object Microsoft.Office.Server.UserProfiles.UserProfileManager($context)
$AllProfiles = $profileManager.GetEnumerator()
$outputCollection = @()

# Loop through profiles and retrieve the desired property
foreach ($profile in $AllProfiles)
{
    $output = New-Object System.Object
    $output | Add-Member -type NoteProperty -Name AccountName -Value $profile["AccountName"].ToString()
    $output | Add-Member -type NoteProperty -Name $findProperty -Value $profile[$findProperty]
    $outputCollection += $output
}

# List all Accounts that do not contain the property
$outputCollection | Where-Object {[bool]$_.($findProperty) -ne $true}






 

Wednesday, May 22, 2013

SharePoint 2013 Search: Moving the Index Partition to the Web Front Ends

I previously wrote a post about Moving the Query Component to a Web Front End. There were questions in regards to the Index Partition/Index Components as well. However, in the meantime I scaled out some of my SharePoint 2013 Search architecture since I had a new "Index Server" provisioned.

While I'll post all of the details of my "scaling out" search experiences, it is recommended that the Index Partition and Query Components live on the same servers;  this is for performance purposes. The more I added to my awesome search results and promoted result blocks across multiple result sources, the slower the search response became. Therefore I decided that we should see what happens if we moved the Index Partition to the web front ends (currently I only have 1 WFE but it would still provide some baseline).

This is all accomplished in PowerShell and/or the SharePoint 2013 Management Console.

Here we go!



Step #1: Get the Search Service Instance and Start on the WFE
#Get Search Service Instance and Start on WFE
$ssi = Get-SPEnterpriseSearchServiceInstance -Identity "<<WFE Server Name>>"
Start-SPEnterpriseSearchServiceInstance -Identity $ssi


Step #2: Wait for the Search Service to Come Online
Get-SPEnterpriseSearchServiceInstance -Identity $ssi

In my full script version, I have a loop that continues until the search service is online.

Step #3: Clone the Active Search Topology
#Clone Active Search Topology
$ssa = Get-SPEnterpriseSearchServiceApplication
$active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa -Active
$clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone –SearchTopology $active


Step #4: Create the New Index Component on the WFE
#Create New Index Component for Index Partition 0
New-SPEnterpriseSearchIndexComponent –SearchTopology $clone -SearchServiceInstance $ssi -IndexPartition 0

-RootDirectory "E:\SPIndex"

I created a folder named SPIndex on the E: drive of the WFE. Modify this for your own location.

This step generates a new Index Component. I had IndexComponent3 and IndexComponent4 already so my new one was IndexComponent5 (yours will probably be different):



Step #5: Activate the Cloned Search Topology with the New Index Component
#Activate the Cloned Search Topology
Set-SPEnterpriseSearchTopology -Identity $clone


Once this is complete you may review your search topology:
#Review new topology
Get-SPEnterpriseSearchTopology -Active -SearchApplication $ssa



Step #6: Monitor the Distribution of the Index
Get-SPEnterpriseSearchStatus -SearchApplication $ssa

The new index component will be degraded until it has sync'ed with the active index components:



In the full script I again have a loop that waits until the new component is Active. Looking at your Search Service Application in Central Admin shows a warning:


Once the new Index Component is active, a new green check appears in the Search Service Application:


Step #7: Clone the Active Search Topology Again
# Clone Again
$ssa = Get-SPEnterpriseSearchServiceApplication
$active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa -Active
$clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone –SearchTopology $active


Step #8: Get the ID of the Index Component to Remove
# Get the Index Search Component ID To Remove
$indexComponentID = (Get-SPEnterpriseSearchComponent -SearchTopology $clone -Identity IndexComponent3).componentID


My component was IndexComponent3 yours may be different.
Use Get-SPEnterpriseSearchStatus -SearchApplication $ssa to see which components you have.

Step #9: Remove the original Index Component
# Remove Search Component
Remove-SPEnterpriseSearchComponent -Identity $indexComponentID.GUID -SearchTopology $clone -confirm:$false


In my case I has had the two components on two servers so I repeated Step #8 and Step #9.


Step #10: Activate Search Topology Again
# Activate  Search Topology Again
Set-SPEnterpriseSearchTopology -Identity $clone



Step #11: Monitor the Distribution of the Index (this time it should be instantaneous)
Get-SPEnterpriseSearchStatus -SearchApplication $ssa

Once the new search topology is activated the Index Partition is moved to the web front end:



What about other WFEs? I will need to add index components to additional WFEs which will be similiar to the process I used to build out my index components on my index servers. More to come on that.

Full Script (fill in the << >> values)

Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue

#Get Search Service Instance and Start on WFE
$ssi = Get-SPEnterpriseSearchServiceInstance -Identity "<<WFE Server Name>>"
Start-SPEnterpriseSearchServiceInstance -Identity $ssi


#Wait for Search Service Instance to come online
do {$online = Get-SPEnterpriseSearchServiceInstance -Identity $ssi; Write-Host "Waiting for service: " $online.Status}
until ($online.Status -eq "Online")


#Clone Active Search Topology
$ssa = Get-SPEnterpriseSearchServiceApplication
$active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa -Active
$clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone –SearchTopology $active

#Create New Index Component for Index Partition 0
New-SPEnterpriseSearchIndexComponent –SearchTopology $clone -SearchServiceInstance $ssi -IndexPartition 0 -RootDirectory "E:\SPIndex"

#Activate the Cloned Search Topology
Set-SPEnterpriseSearchTopology -Identity $clone


#Review new topology
Get-SPEnterpriseSearchTopology -Active -SearchApplication $ssa


#Monitor Distribution of Index
do {$activeState = Get-SPEnterpriseSearchStatus -SearchApplication $ssa | Where-Object {$_.Name -eq "IndexComponent5"}; Write-Host "Waiting for active distribution: " $activeState.State}
until ($activeState.State -eq "Active")


# Clone Again
$ssa = Get-SPEnterpriseSearchServiceApplication
$active = Get-SPEnterpriseSearchTopology -SearchApplication $ssa -Active
$clone = New-SPEnterpriseSearchTopology -SearchApplication $ssa -Clone –SearchTopology $active


# Get the Index Search Component ID To Remove
$indexComponentID = (Get-SPEnterpriseSearchComponent -SearchTopology $clone -Identity <<Index Component Name>>).componentID


# Remove Search Component
Remove-SPEnterpriseSearchComponent -Identity $indexComponentID.GUID -SearchTopology $clone -confirm:$false


# Activate  Search Topology Again
Set-SPEnterpriseSearchTopology -Identity $clone


#Monitor Distribution of Index
do {$activeState = Get-SPEnterpriseSearchStatus -SearchApplication $ssa | Where-Object {$_.Name -eq "<<New Index Component Name>>"}; Write-Host "Waiting for active distribution: " $activeState.State}
until ($activeState.State -eq "Active")


 

Tuesday, May 21, 2013

SharePoint 2013 Search: Adding Managed Properties to Display Templates

Based on some feedback from a previous post, a reader commented that it would be nice to see how to add managed properties to a search display template. The most common method is a one-to-one mapping, however, you may link a search result item property to multiple managed properties. This post explains both methods.

While the recommended approach is to use Design Manager to upload display templates, I find it much easier to make copies and modifications using SharePoint Designer 2013. You may access the search display templates from SharePoint Designer 2013 using the method explained in this post.

One-to-One Mapping

Each Search display template contains default managed properties. They appear in the <mso:ManagedPropertyMapping> tag at the top of each template:


{Click on image to see larger view}
Sometimes when making copies of the templates or modifying existing ones, the quotes become http encoded:

{Click on image to see larger view}


It doesn't matter as either way will work. The syntax for one-to-one mapping is as follows:

 
'<<property name to be used in current item>>':'<<managed property name>>'
 
 
To add a new managed property, simply add another entry. For example, if I had a managed property named "CustomerID", I would add 'CustomerID':'CustomerID', to the <mso:ManagedPropertyMapping> tag:
 
 
 
For maintainability it is recommended to name the current item property name the same as the managed property name. Once that is added, you may now use the new property by referencing it from the current result item:
 
ctx.CurrentItem.CustomerID
 
Once you save your changes, you need to update your result type such that the query component knows which properties need to be returned for the search result.
 
 
One-to-Many Mapping
If you take a look at the Item_Video_CompactHorizontal.html template, you'll notice that they are mapping a search result item property to multiple managed properties:
 
{Click on image to see larger view}
The syntax here is a little different:
 
'<<search result item property name>>'{search result item property name}:'<<list of managed properties>>'
 
The list of managed properties are separated by semicolons. I am assuming that the value of the search result item is populated with the first managed property that has a value based on the order listed.
 
To use the managed property value within the template code/mark-up, you must get the value from the context:
 
var imageURL = $getItemValue(ctx, "Picture URL");
 
 
 


 



Monday, May 20, 2013

SharePoint 2013 Search: Modifying Promoted Result Displays

A question came up during my Search sessions at SPS Baltimore this past weekend. It was in regards to Promoted Results taking the place of Best Bets and the icon being used.

The icon is no longer a star but a blue check mark:

Search uses the Item_BestBet display template to present these promoted results. You may find the template in your Search Display Templates folder:
 


 
You may make modifications to this template to change how promoted results are rendered. The specific question dealt with the icon. There is a div and an img tag located in the template file:
 



This is using a sprite image named searchresultsui.png which is made up of various icons that are used within the search results. Obviously it is using the blue checkmark portion of the sprite. If you wanted, you could modify the image tag to use a different image as the promoted results icon.





 

Tuesday, May 14, 2013

SharePoint 2013 Search: Adding a Hover Panel to the Video Horizontal Display Template


Check out the whole SharePoint 2013 Solution Series
New Titles Added Weekly!

In my previous post on Enhancing Video Results, I demonstrated how to display Video results in a horizontal fashion using the out-of-the-box Video horizontal template. However, this display does not incorporate a hover panel and thus nothing pops up when mousing over the results. No problem. I figured out how to add a hover panel to the template in just a few easy steps.

First, navigate to the Search Center display templates via SharePoint Designer 2013, similiar to the process explained in this post. For simplicity I am going to modify the display template file in-place but the recommended approach would be to make a copy and use that.

Locate the Item_Video_CompactHorizontal.html file, right-click, and select Edit File in Advanced Mode:



 
 
Paste this code at the top as shown in the image below:
 
var id = ctx.ClientControl.get_nextUniqueId();
var itemId = id + Srch.U.Ids.item;
var hoverId = id + Srch.U.Ids.hover;
var hoverUrl = "~sitecollection/_catalogs/masterpage/Display Templates/Search/Item_Video_HoverPanel.js";
$setResultItem(itemId, ctx.CurrentItem);
ctx.currentItem_ShowHoverPanelCallback = Srch.U.getShowHoverPanelCallback(itemId, hoverId, hoverUrl);
ctx.currentItem_HideHoverPanelCallback = Srch.U.getHideHoverPanelCallback();


Notice I am using the out-of-the-box Item_Video_HoverPanel .

Next, scroll down to the main <div> and change the id to use _#= $htmlEncode(itemId) =#_



(Click on image to display larger)
 
 Add the following code to that very same <div> tag:

onmouseover="_#= ctx.currentItem_ShowHoverPanelCallback =#_"
onmouseout="_#= ctx.currentItem_HideHoverPanelCallback =#_"
(Click on image for larger view)
 
Now add the following <div> after the first <div>:
 
<div id="_#= $htmlEncode(hoverId) =#_" class="ms-srch-hover-outerContainer"></div>




 
Save the changes to the template. Navigate to your Search Center and perform a search that returns Video results:
 
 

 
 
Hovering over the results shows the hover panel preview!!!
 
 
 





 

Monday, May 13, 2013

SharePoint 2013: Enhancing Video Search Results


Check out the whole SharePoint 2013 Solution Series
New Titles Added Weekly!

In SharePoint 2013 Search there are several out-of-the-box query rules to display ranked result blocks of various result types (.e.g Word, Excel, PowerPoint, etc.). These are triggered based on specific action terms that appear either in the beginning or end of a search query (or both). However, Videos is not one of them.

Therefore, it would be nice if someone performed a search query using "video" or "videos" that a promoted result block of video results would appear at the top of the results. Easier done than said!

Navigate to your Site Settings from within your Search Center site collection and click on Search Query Rules under Site Collection Administration:

 
Select Local SharePoint Results (System) as the Result Source:

 
 
Click on the New Query Rule link:


Add the Rule Name, select Query Contains Action Term, enter "video;videos" in the Action term is one of these phrases:

 
Click on Add Result Block.
 
 
Modify the Block Title. Change Search this Source to Local Video Results (System) and increase the amount of Items as desired (I used 6).  Expand the Settings section.
 
Select the "More" link since there is already a Video Results page and enter the value shown in the image below. Select Video Item as the Display Template:
 



Click OK and then click Save on the New Query Rule page.

Navigate to your Search Center main page and perform a search using "videos" in the query:





The video result block appears at the top and displays the video results. The results show hover panels when moused over.

There is another way to display these results using an out-of-the-box horizontal video display template. If you go back into your Search Query Rules, edit the Video query, and then edit the Result Block, you may change the Display Template setting to just the Video entry:




Now the results are displayed horizontally along the top:


 
 
This presents well but there is no hover! You can easily modify the template (or make a new copy as the recommended approach) to display the hover. I will have those steps in another post soon!
 
 
 



 

Friday, May 10, 2013

SharePoint 2013 Search: Creating an Image Horizontal Result Block

SharePoint 2013 contains templates to display both videos and people in a horizontal fashion presenting a nice presentation in the Everything search results. For an example of the Video horizontal display see this post.

I thought it would be nice to also have this functionality for images as well as attempt to display the hover panel on the items (since the people and video horizontal displays do not incorporate the hover panel). Also, one of my blog readers happened to query about an image horizontal display - so it was time to implement!!

Launch SharePoint Designer 2013 and navigate to the search center display templates (similiar to the steps here).

Locate the Item_Picture.html, right-click and select Copy:


 
Right-click again and select Paste:

 
Rename the copied file to Item_Picture_CompactHorizontal:


Right-click again and select Edit File in Advanced Mode:


Rename the title and the main div id:

 
Add the following code as shown in the image below:
 
<!--#_ 
                if (!Srch.U.n(ctx.CurrentItem.ParentTableReference) && ctx.CurrentItem.ParentTableReference.TotalRows > 1) {
_#-->
 

<!--#_ 
                } else {
_#-->

 



Scroll to the bottom and add an additional closing bracket:


Between the if and the else that you pasted first, enter the following code as shown in the image below:

            <div id="_#= $htmlEncode(itemId) =#_" name="Item" class="ms-srch-people-intentItem" onmouseover="_#= ctx.currentItem_ShowHoverPanelCallback =#_" onmouseout="_#= ctx.currentItem_HideHoverPanelCallback =#_">
    <div id="ImageInfo">
<!--#_ 
       var pathEncoded = $urlHtmlEncode(ctx.CurrentItem.Path);
                            var encodedName = $htmlEncode(ctx.CurrentItem.Title);
_#-->

                    <ul id="ImageCard">
                       <li id="ImagePic">
        <a clicktype="Result" href="_#= pathEncoded =#_" title="_#= encodedName =#_">
                               <img id="PicPreview" src="_#= pathEncoded =#_" height="80px" width="80px"/>
                            </a>
      </li>
       <li id="ImageTitle">
        <div id="imageTitle" class="ms-textSmall ms-srch-ellipsis" title="_#= encodedName =#_"> _#= encodedName =#_ </div>
       </li>
     </ul>
                  <div id="_#= $htmlEncode(hoverId) =#_" class="ms-srch-hover-outerContainer"></div>
    </div>
            </div>




Save the the changes and then navigate to your Search Center.

From your Search Center site settings, select Search Query Rules from the Site Collection Administration section:


Select the Local SharePoint Results (System):


After the Query Rules load on the page, scroll down and find the Image entry. From the drop-down menu select Copy:


Change the Rule name:

Scroll down to the Actions sections and click on edit to edit the result block:
 
 

Change the Query. I was not getting expected results from the InternalFileType property. Therefore I changed my query filter to "(ContentType:PictureItem OR  ContentType:Image)".

I also changed the amount of items to 6:

In the Settings select This block is always shown above core results and also change the Item Display Template to the new Picture Horizontal template:
 
Click OK. Click Save on the Edit Query Rule page.
 
 
Navigate to your search page and peform a search for images:


The images display horizontally and the hover works as well:


 
 
Search On!!!