Showing posts with label Search. Show all posts
Showing posts with label Search. Show all posts

Thursday, November 19, 2015

SharePoint 2013 Result Source Only Include Content From Current Site NOT Sub Sites

Hello Blog Readers,

Sorry for the delay in posts recently things at work in terms of projects, but I did have an extremely helpful Result Source Syntax you should know!  From the title of this blog article you have probably guessed what I will discuss, how to actually only search on the current site!

I can’t believe how many copy and paste blogs are out there since everyone’s “solution” of Path:{Site} or Path:{Site.URL} does not work!  I was so frustrated after clicking through pages of Google links (dear god I made it to page 3… where results go to die) that I just sat down and tried to figure out a solution myself.
For those of you who don’t want the journey or explanation the key to your success is to include this as part of your query:
WebId={Site.ID}

Why is The Path Solution Incorrect?
The Path solution is incorrect since Path:{Site} will include any content from your sub sites which matches the criteria.  This is because the child sites includes the path of the parent site, which means you will always get the data from the sub sites which inherit from the parent’s Path.  You may be thinking well Dan, why don’t you just use Path={Site} instead of contains.  If you have tried this syntax on its own, you most likely only received the Home Page of the site from which you were running the query from.  Content within the site obviously does not have the URL of the homepage, so using equals will only return the one page which matches the path exactly.  In short, you can use Path:{Site} when you are trying to exclude contents from parent sites, but include content from the current site and it’s children.

How to Return Results ONLY From the Current Site:
To only obtain results from the site from which the query is being run, WebId={Site.ID} should be used.  WebId is an out of the box managed property which houses the site’s GUID  / ID, so essentially what we are saying in the above is that we want to only return items where the WebId is equal to the current site’s GUID/ID from which the query is being issued from.

Simple Example Query:
SPContentType=”Item” AND WebId={Site.ID}

This query will only retrieve items which match the item content type display name and where the WebId is equal to the current sites GUID / ID.  If you were to try this same query from a top level site utilizing Path:{Site} instead of WebId, like the other blogs and sites suggest, you will retrieve Items with this content type from all of the sub sites beneath this path.  The query above will ONLY return items from the current site J
Best of Luck!

Dan

Wednesday, December 31, 2014

Log Managed Property Values Retrieved From a Display Template

Hello Interwebs!
I have been doing a ton of search work lately and just wanted to share a useful script for tracking down those pesky Managed Property Values.  I have been wanting to write a search series, but just can’t seem to find the time to put pen to paper (or fingers to keyboard in my case) to get them written up!

When I first started working with search I think my biggest headache was to tell which managed properties were being retrieved and what the values were for each managed property.  The below script can be added to your display template to log the managed property name & value to your console window for each search result returned.

for (var p in ctx.CurrentItem)
                             {
 console.log(p + ":" + $getItemValue(ctx, p));
                             }

This code can be implemented within any display template, but for this example I will be using the Item_CommonItem_Body display template
(NOTE after your test you should remove the code snippet due to compatibility issues for some browser versions & that there really isn’t a reason to log these values to console outside of testing) I am using this particular template as an example, but any display template which is called from search could be used.
Below is the default code from Body tag of our Item_Common_Body display template where I have added the script to iterate through the managed properties.

<body>
    <div id="Item_CommonItem_Body">
<!--#_


        var id = ctx.CurrentItem.csr_id;
        var title = Srch.U.getHighlightedProperty(id, ctx.CurrentItem, "Title");
        if ($isEmptyString(title)) {title = $htmlEncode(ctx.CurrentItem.Title)}

        var useWACUrl = !$isEmptyString(ctx.CurrentItem.ServerRedirectedURL);
        if(ctx.ScriptApplicationManager && ctx.ScriptApplicationManager.states){
            useWACUrl = (useWACUrl && !ctx.ScriptApplicationManager.states.openDocumentsInClient);
        }

        var appAttribs = "";
        if(!useWACUrl)
        {
            if (!$isEmptyString(ctx.CurrentItem.csr_OpenApp)) { appAttribs += "openApp=\"" + $htmlEncode(ctx.CurrentItem.csr_OpenApp) + "\"" }; 
            if (!$isEmptyString(ctx.CurrentItem.csr_OpenControl)) { appAttribs += " openControl=\"" + $htmlEncode(ctx.CurrentItem.csr_OpenControl) + "\"" };
        }

        var showHoverPanelCallback = ctx.currentItem_ShowHoverPanelCallback;
        if (Srch.U.n(showHoverPanelCallback)) {
            var itemId = id + Srch.U.Ids.item;
            var hoverId = id + Srch.U.Ids.hover;
            var hoverUrl = "~sitecollection/_catalogs/masterpage/Display Templates/Search/Item_Default_HoverPanel.js";
            showHoverPanelCallback = Srch.U.getShowHoverPanelCallback(itemId, hoverId, hoverUrl);
        }
        var displayPath = Srch.U.getHighlightedProperty(id, ctx.CurrentItem, "Path");
        if ($isEmptyString(displayPath)) {displayPath = $htmlEncode(ctx.CurrentItem.Path)} 
        var url = ctx.CurrentItem.csr_Path;
        if($isEmptyString(url)){
            if(useWACUrl)
            {
                url = ctx.CurrentItem.ServerRedirectedURL;
            } else {
                url = ctx.CurrentItem.Path;
            }        
        }
        ctx.CurrentItem.csr_Path = url;
        var pathLength = ctx.CurrentItem.csr_PathLength;
        if(!pathLength) {pathLength = Srch.U.pathTruncationLength}

        var maxTitleLengthInChars = Srch.U.titleTruncationLength;
        var termsToUse = 2;
        if(ctx.CurrentItem.csr_PreviewImage != null)
        {
            maxTitleLengthInChars = Srch.U.titleTruncationLengthWithPreview;
            termsToUse = 1;
        }

        var clickType = ctx.CurrentItem.csr_ClickType;
        if(!clickType) {clickType = "Result"}        
_#-->    
        <div id="_#= $htmlEncode(id + Srch.U.Ids.body) =#_" class="ms-srch-item-body" onclick="_#= showHoverPanelCallback =#_">
<!--#_
            if (!$isEmptyString(ctx.CurrentItem.csr_Icon)) {
_#-->
                <div class="ms-srch-item-icon"> 
                    <img id="_#= $htmlEncode(id + Srch.U.Ids.icon) =#_" onload="this.style.display='inline'" src="_#= $urlHtmlEncode(ctx.CurrentItem.csr_Icon) =#_" />
                </div>
<!--#_
            }

                                          var titleHtml = String.format('<a clicktype="{0}" id="{1}" href="{2}" class="ms-srch-item-link" title="{3}" onfocus="{4}" {5}>{6}</a>',
                                          $htmlEncode(clickType), $htmlEncode(id + Srch.U.Ids.titleLink), $urlHtmlEncode(url), $htmlEncode(ctx.CurrentItem.Title), 
                                          showHoverPanelCallback, appAttribs, Srch.U.trimTitle(title, maxTitleLengthInChars, termsToUse));
                                          
                                          }
_#-->       
            <div id="_#= $htmlEncode(id + Srch.U.Ids.title) =#_" class="ms-srch-item-title"> 
                <h3 class="ms-srch-ellipsis">
                    _#= titleHtml =#_
                </h3>
            </div>
<!--#_ 
            if (!$isEmptyString(ctx.CurrentItem.HitHighlightedSummary)) { 
_#-->
                <div id="_#= $htmlEncode(id + Srch.U.Ids.summary) =#_" class="ms-srch-item-summary">_#= Srch.U.processHHXML(ctx.CurrentItem.HitHighlightedSummary) =#_</div>
                
       


<!--#_ 
            }
            var truncatedUrl = Srch.U.truncateHighlightedUrl(displayPath, pathLength);
_#-->
            <div id="_#= $htmlEncode(id + Srch.U.Ids.path) =#_" tabindex="0" class="ms-srch-item-path" title="_#= $htmlEncode(ctx.CurrentItem.Path) =#_" onblur="Srch.U.restorePath(this, '_#= $scriptEncode(truncatedUrl) =#_', '_#= $scriptEncode(ctx.CurrentItem.Path) =#_')" onclick="Srch.U.selectPath('_#= $scriptEncode(ctx.CurrentItem.Path) =#_', this)" onkeydown="Srch.U.setPath(event, this, '_#= $scriptEncode(ctx.CurrentItem.Path) =#_', '_#= $scriptEncode(truncatedUrl) =#_')" >
                _#= truncatedUrl =#_
            </div>
        </div>
      


<!--#_
        if (!$isEmptyString(ctx.CurrentItem.csr_PreviewImage)) 
        {
            var altText = Srch.Res.item_Alt_Preview;
            if(!$isEmptyString(ctx.CurrentItem.csr_PreviewImageAltText)){
                altText = ctx.CurrentItem.csr_PreviewImageAltText;
            }

            var onloadJS = "var container = $get('" + $scriptEncode(id + Srch.U.Ids.preview) + "'); if(container){container.style.display = 'inline-block';}" +
                           "var path = $get('" + $scriptEncode(id + Srch.U.Ids.path) + "'); if (path) { Srch.U.ensureCSSClassNameExist(path, 'ms-srch-item-preview-path');}" +
                           "var body = $get('" + $scriptEncode(id + Srch.U.Ids.body) + "'); if (body) { Srch.U.ensureCSSClassNameExist(body, 'ms-srch-item-summaryPreview');}";

            var previewHtml = String.format('<a clicktype="{0}" href="{1}" class="ms-srch-item-previewLink" {2}><img class="ms-srch-item-preview" src="{3}" alt="{4}" onload="{5}" /></a>', 
                                            $htmlEncode(clickType), $urlHtmlEncode(url), appAttribs, $urlHtmlEncode(ctx.CurrentItem.csr_PreviewImage), $htmlEncode(altText), onloadJS);
_#-->       
            <div id="_#= $htmlEncode(id + Srch.U.Ids.preview) =#_"  class="ms-srch-item-previewContainer"> 
                _#= previewHtml =#_
            </div>
<!--#_
        }
         for (var p in ctx.CurrentItem)
  {
       console.log(p + ":" + $getItemValue(ctx, p));
  }
  
         _#-->
    </div>
</body>
Now that we have added the script, saved and published the display template we are ready to see what is brought back from our search results!

  1.  Open your browser’s developer tools
  2.  i.e. FireBug, Chrome Tools, F12, etc.
  3.  Enter a search query into the search box which will return results
  4. You can use * to grab everything
  5. Select the console tab in your developer tools
  6. Bask in the awesome... There are actually more properties for this particular item than the screenshot shows, but I can only grab so many with a screen capture :) 

In a future post I will be walking through how to add new Managed Properties to your display templates and how to surface them via the item results and hover panels.

Hope This Helps!
Dan