Thursday, April 24, 2014

Solution to displaying attachments for a list item in a search result

Matthew McDermott has done it again people! He has given me yet another hard problem to solve. This time it’s about getting the number of attachments of a list item in your search results. And as an added bonus, I’m throwing in the attachment links as well (which actually is a side effect).

image

As it turns out there is no managed property named anything related to attachment or count which will return the number of attachments or the attachment links. That is, if you check the TechNet list or view the search schema via the UI.
Topics covered in this post:
  • Debugging using Search Query Tool v2 – with experimental features turn on
  • The undocumented managed property LinkOfficeChild
  • Custom display templates

By now, everyone digging for data related to search should have downloaded SharePoint 2013 Search Query Tool v2 from Codeplex, and you should also have enabled the experimental features as I mention in the release post for the tool.

I started by creating a list, adding an item and finally adding two attachments to the item.

image

Once the item was crawled I fired up the Search Query Tool, searched for OneOne, and clicked the View all properties link for the item.

image

In the properties window I then started scanning for the names of my attachments, and it’s there!!!! There’s an undocumented managed property named LinkOfficeChild which gives us exactly what we need. If you split the value on line break you will get the count. Problem solved!

Steve Curran actually mention this property briefly in an old post from 2009 regarding MOSS search.

image

Below is a sample display template which lists the number of attachments and the attachment links as seen in the screenshot at the top.

<html xmlns:mso="urn:schemas-microsoft-com:office:office" xmlns:msdt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882">
<head>
    <title>Item with attachments</title>

    <!--[if gte mso 9]><xml>
    <mso:CustomDocumentProperties>
    <mso:TemplateHidden msdt:dt="string">0</mso:TemplateHidden>
    <mso:MasterPageDescription msdt:dt="string">Viser standardmalen for resultatelementet.</mso:MasterPageDescription>
    <mso:ContentTypeId msdt:dt="string">0x0101002039C03B61C64EC4A04F5361F385106603</mso:ContentTypeId>
    <mso:TargetControlType msdt:dt="string">;#SearchResults;#</mso:TargetControlType>
    <mso:HtmlDesignAssociated msdt:dt="string">1</mso:HtmlDesignAssociated>
    <mso:ManagedPropertyMapping msdt:dt="string">'Title':'Title','LinkOfficeChild':'LinkOfficeChild'</mso:ManagedPropertyMapping>
    <mso:HtmlDesignConversionSucceeded msdt:dt="string">True</mso:HtmlDesignConversionSucceeded>
    <mso:HtmlDesignStatusAndPreview msdt:dt="string">https://techmikael.sharepoint.com/search/_catalogs/masterpage/Display%20Templates/Search/Item_Default_Attachment.html, Conversion successful.</mso:HtmlDesignStatusAndPreview>
    </mso:CustomDocumentProperties>
    </xml><![endif]-->
</head>
<body>
    <div id="Item_Default">
        <!--#_
            if(!$isNull(ctx.CurrentItem) && !$isNull(ctx.ClientControl)){
            var id = ctx.ClientControl.get_nextUniqueId();
            var itemId = id + Srch.U.Ids.item;
            var linkString = ctx.CurrentItem.LinkOfficeChild;
            if($isEmptyString(linkString) == false) {
                var attachmentLinks = linkString.split(/\n+/);
                var numberOfLinks = attachmentLinks.length;
                    var linkMarkup = "";
                    for(var i=0; i<numberOfLinks; i++) {
                        linkMarkup = linkMarkup + "<a href='" + attachmentLinks[i] + "'>" + attachmentLinks[i] + "</a><br />";
                    }
                }
                _#-->
        <div id="_#= $htmlEncode(itemId) =#_" name="Item" data-displaytemplate="DefaultItem" class="ms-srch-item">
            <h3 class="ms-srch-ellipsis">_#= ctx.CurrentItem.Title =#_</h3>
            <div>Attachment Count: _#=numberOfLinks=#_</div>
            <div>Attachment Links: _#=linkMarkup=#_</div>
        </div>
        <!--#_
        }
        _#-->
    </div>
</body>
</html>

5 comments:

  1. Thanks, Mikael! This is a life saver.

    ReplyDelete
  2. Thank you very much for your post and for your help.!!!
    This solution works properly in my list item template.

    ReplyDelete
  3. Hi Mikale, I have an issue and it seems i can't get my head around why this is not working, which i believe use to work. The attachment also indexed it means if we try to search for a given word in attachment document then the search should return the related item. I saw it working in past, but this doesn't work now on SPO i created a fresh new tenant with no customization and tried with all possible documents format (txt,pdf,doc,docx) as attachment to custom list item, i can't get the item appear by search term in document. Is 'ExcludeFromSummary' managed property causing issue here? or something else? Any pointers ?

    ReplyDelete
  4. Nice Post as usual. Just what I was looking for.

    ReplyDelete