SharePoint 2010–Returning Document ID in Search Results

(Post courtesy Sean Earp, with research and XSLT authoring by Alaa Mostafa)

One of my favorite features of SharePoint 2010 is the Document ID.

As discussed in the MSDN article Developing with Document Management Features in SharePoint Server 2010 (ECM):

A document ID is a unique identifier for a document or document set and a static URL that opens the document or document set associated with the document ID, regardless of the location of the document. Document IDs provide:

  • A way to reference items such as documents and document sets in SharePoint Server 2010 that is less fragile than using URLs. URLs break if the location of the item changes. In place of the URL, the document ID feature creates a static URL for each content item with a document ID assigned to it.

  • More flexible support for moving documents or document sets at different points in the document life cycle. For example, if you create a document on a MySite or Workspace page and then publish it on a team site, the document ID persists and travels with the document, circumventing the broken URL problem.

  • A document ID generator that assigns a unique document ID to items. You can customize the format of the IDs that the service generates. By using the document management API, you can write and use custom document ID providers.

image

When browsing a document library with this feature enabled, you can display the Document ID column, and you will be able to see the Document ID for a given document.  Easy enough, and useful if you need to reference this Document ID in another system.

This works great when you can browse a document library, perhaps using the new metadata navigation and filtering capabilities of SharePoint 2010, but if your document library is holding thousands and thousands of documents, users may resort to using search to find the document they are looking for.  Unfortunately, SharePoint search does not display the document ID is the search results by default.

image

Fortunately, SharePoint indexes Document IDs as a managed property by default, which means that with a little magic, we can add the Document ID into the search results.

In a nutshell, SharePoint retrieves the search results as XML, and uses XSLT to transform the XML into the pretty results you see on the search results page.  Same basic concept as HTML (which has your content) and CSS (which styles that content).  We just need to tell SharePoint to return the managed property with our Document ID, and then update the XSLT to display that managed property in the search results. 

It is not as hard as it sounds.

Assumptions: I assume you have enabled the Document ID feature on the site collection, all documents have been assigned Document IDs, and a full crawl has been done of the site.  I also assume you are a site collection administrator with full permissions to the site collection.

From your Search Results page  in the site collection (wherever you have it),   click on Page –> Edit (or Site Actions –> Edit Page).  You will see a ton of zones and web parts (such as the Refinement Panel, Search Statistics, Search Box, etc.  You can customize the heck out of the search results page, and move things all over the place.

image

For now, however, we are just going to modify the Search Core Results web part that contains…er… the core search results.  How intuitive!

Edit the Search Core Results web part, and expand the section that says “Display Properties”.  Uncheck the box that says “Use Location Visualization”.  I have no idea why this option is named as it is… this is really the option that lets you edit the fetched properties and XSL.

image

As a quick aside… although you can edit the fetched properties and XSL directly from the web page properties, the experience is horrible.  I strongly recommend using an XML editor like Visual Studio or NotePad++

In the Fetched Properties section you will see a number of columns that look like the following.  these are the managed properties that are returned by SharePoint Search

 <Column Name="PictureHeight"/>  <Column Name="PictureWidth"/>

Somewhere before the closing </Columns> tag, add a:

 <Column Name="spdocid"/>

(Note: if you are using SharePoint search instead of FAST search replace all instances of “spdocid” with “DocID”)

This will cause SharePoint to return the Document ID in the search results XML.  Now let’s modify the XSL so that we display the ID in the search results.  Click on the “XSL Editor…” and copy the XSL into your XML editor of choice (or, if you like pain, just edit the 938-line long XSL sheet in a browser that does no validation or color coding.  Your choice.)

At the top of the XSL is a list of parameter names.  Add in the following parameter (order does not matter)

 <xsl:param name="spdocid" />

image

Next, search for “DisplayAuthors.  After the DisplayAuthors call template, we are going to add a new call template called “DisplayID” to… well, display the ID. The template is wrapped in a conditional to ensure that if there is NOT a document ID, that it does not attempt to display a null value. 

Add the following: following lines:

               <xsl:if test="string-length($hasViewInBrowser) &gt; 0">
                
                      <xsl:call-template name="DisplayID">
                        <xsl:with-param name="spdocid" select="spdocid" />
                        <xsl:with-param name="browserlink" select="serverredirectedurl" />
                        <xsl:with-param name="currentId" select="$currentId" />
                      </xsl:call-template>
                  
              </xsl:if>

image

Search for “DisplayString” and we will add a section to call our template, display the ID (along with a URL that links to the document), and we’ll put brackets around the Document ID so it stands out visually.  Add the following:

   <xsl:template name="DisplayID">
    <xsl:param name="spdocid" />
    <xsl:param name="currentId" />
    <xsl:param name="browserlink" />
    <xsl:if test="string-length($spdocid) &gt; 0">
      <xsl:text xml:space="default"> [ </xsl:text>
      <a href="{concat($browserlink, $ViewInBrowserReturnUrl)}" id="{concat($currentId,'_VBlink')}">
        <xsl:value-of select="$spdocid" />
      </a>
      <xsl:text xml:space="default"> ] </xsl:text>
    </xsl:if>
  </xsl:template>

image

We’re almost done!  Select all your XSL, copy it, and paste it back into your SharePoint window, hit Save –> Okay –> Check In –> Publish

Voila!  The Document ID now shows up in the search results with a clickable link back to the source document.

image

Random troubleshooting tip:  If you get the message “Property doesn't exist or is used in a manner inconsistent with schema settings”, this typically means one of two things:

  1. You created a custom managed property and have not yet run a full crawl so that this property does not exist in the index (this property is mapped out of the box, so it does not apply here)
  2. You are using the wrong managed property.  FAST search uses “spdocid” while SharePoint search uses “DocId”

image

image

Attachments: I have attached a copy of the XSL I used for the above post to save you time copying and pasting into the right sections.  It works for me with SharePoint search, but use on a test server first and at your own risk.

SharePoint_Search_XSL_DocID.xsl