A few people have asked about how to more closely integrate the standard SharePoint Search Core Results Web Part with the related topics information that is maintained by the SharePoint Module. There are a number of different use cases, but in this post I'll focus on a common request - to be able to include related topics in the metadata returned by a text search and display them in the Search Core Results Web Part.
The procedure for doing this is actually quite simple. All you need to do is
- Add the field(s) you want to display to the list of Managed Properties for the crawler.
- Add the managed property (or properties) to the list of columns returned by the Search Core Results Web Part.
- Update the XSLT stylesheet used to render the results.
Adding Fields to the Crawler Managed Properties
The first step is to make sure that the related topics field you want is added to the list of managed properties for the crawler. To do this you must go to the SharePoint Central Administration site and select the SSP for the web application. The click on the link Search > Search Settings and on the page that is displayed, click on the link "Metadata property mappings". This shows the following screen:

Click on "Create New Managed Property". From this page you can add a new property that will be populated by the search crawler and specify which field(s) provide a value for the property. Note that you can specify multiple properties here so if you want to, you can combine the value of several different related topics fields into a single more generic property. For example on the demo news story site we have our stories classified by three related topics fields : Who, What and Where. We can choose either to create separate managed properties for each of these fields or to combine them all into a single field. I'll show this latter option in the example below.
To create the new managed property, you should enter the following information into the fields:
Name and Type: The name for the managed property gets used in the XML generated by the Search Core Results Web Part, so it is best to create a name string with simple ASCII characters and no spaces. For the type, select the Text option.
Mappings to crawled properties: Add mappings for the related topics field(s) you want to be indexed. Note that if you specify multiple mappings you have the choice of either adding all of the mapped values or of treating the list as a priority list of mappings that justs adds the values for the first mapped field found. (NOTE: If you cannot find the related topics fields in the list of crawled properties, this probably means that you have no documents with a value in this field - to fix this, create a new document or update an existing one to add a value to the related topics field, save the document (and publish it if necessary) and then run the crawler or wait for an incremental crawl or full crawl to run.).
Use in Scopes: Leave this box unchecked.
This is how my new managed property mapping looks - I want to map three related topics fields (ND_What, ND_Where, ND_WHo) to a single property called "Classification".
alt="Screenshot of the completed New Managed Property form."/>
Now run the crawler again (or wait for it to run again). You need a full crawl for this new property to get populated correctly.
Add the Managed Property to the Columns returned by the Search Core Results Web Part
To get our search to return the new managed property we just need to configure the query columns. To do this, go to the search results page and put it into edit mode:

Bring up the property editor for the Search Core Results Web Part and expand the section titled "Results Query Options". Edit the "Selected Columns" property in that section (it is easiest to do this by bringing up the text editor dialog for the field). Add a column definition for the new managed property. The XML is simply:
<Column Name="Property Name"/>

Your query should now be returning the related topics field values in the XML that is styled by the Search Core Results Web Part - to check this you could just change the web part to use the debug stylesheet that comes with the TMCore SharePoint Module. I usually do this by uploading the debug stylesheet to a document library and then putting a link to it into the "XSL Link" property (found in the "Miscellaneous" property group). For my example site, this is what I get in the Search Results Web Part when I now use the debug stylesheet (I've highlighted the related topics field values that are returned by the new managed property):

Use XSLT to style the results
OK, so far so easy :-). Now for the tricky bit - the value returned by the related topics fields is actually a set of 4 values for each related topic - in order, these are the topic name, the topic OID, a link to the item that the topic represents (if any) and a PSI for the topic. Each of these four values are separated with the separator string ';#'.
<classification>
The Art Of War (1.0 PUBLISHED)
;#5868
;#http://dev-server-2/what/Pages/TheArtOfWar.aspx
;#urn:x-versionsupport.networkedplanet.com:sp::...:1.0:PUBLISHED
;#;Troy (1.0 PUBLISHED)
;#5913
;#http://dev-server-2/where/Pages/Troy.aspx
;#urn:x-versionsupport.networkedplanet.com:sp::...:1.0:PUBLISHED
;#;Odysseus ( PUBLISHED)
;#6085
;#http://dev-server-2/who/Pages/Odysseus.aspx
;#urn:x-versionsupport.networkedplanet.com:sp::...::PUBLISHED;#
</classification>
So we need some slightly fancy XSLT to parse the field values. This is the XSLT I have come up with:
<!-- Template to render a list of related topics field values -->
<xsl:template name="DisplayClassification">
<xsl:param name="str" />
<xsl:if test='string-length($str) > 0'>
-
<xsl:call-template name="split">
<xsl:with-param name="string" select="$str"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="node()|@*" mode="split" name="split">
<xsl:param name="string" select="string()"/>
<xsl:variable name="sep" select="';#'"/>
<!-- Extract the first field into $tmp -->
<xsl:variable name="tmp" select="substring-before($string, $sep)"/>
<!-- If multiple fields are concatenated together, topics can end up with a ';'
prefix on their name.The following ensures that $topicname is stripped
of this if necessary -->
<xsl:variable name="topicname">
<xsl:choose>
<xsl:when test="starts-with($tmp,';')">
<xsl:value-of select="substring-after($tmp, ';')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$tmp"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="rest1" select="substring-after($string, $sep)"/>
<xsl:variable name="topicid" select="substring-before($rest1,$sep)"/>
<xsl:variable name="rest2" select="substring-after($rest1,$sep)"/>
<xsl:variable name="link" select="substring-before($rest2,$sep)"/>
<xsl:variable name="rest3" select="substring-after($rest2,$sep)"/>
<xsl:variable name="urn" select="substring-before($rest3,$sep)"/>
<xsl:variable name="nextitem" select="substring-after($rest3,$sep)"/>
<!-- Render the topic and link as an HTML anchor. You could replace
this with your own rendering code -->
<xsl:if test="$topicname and $link">
<a>
<xsl:attribute name="href">
<xsl:value-of select="$link"/>
</xsl:attribute>
<xsl:value-of select="$topicname"/>
</a>
</xsl:if>
<!-- Check if a recursive call should be made to parse the rest of the field -->
<xsl:if test="contains($nextitem,$sep)">
<xsl:text>, </xsl:text>
<xsl:call-template name="split">
<xsl:with-param name="string" select="$nextitem"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
You can download this snippet of code from here: Download file
The first template is the one that you can call from wherever you want to render a managed property that contains the value of one or more related topics fields. The str parameter must contain the content of the managed property to render. The second template is a recursive call that parses the first four fields from the string, extracting the values to four local variables and then renders the topic name and link as an HTML anchor element (you could replace this with your own rendering code), finally if there is at least one separator left in the rest of the field value, then it makes a recursive call that will parse the next four fields and so on until we are done.
This is the final result - in this case I'm just calling my rendering as part of the rendering for result metadata, of course you can use XSLT to render those related topics any way you like in the results list.

Conclusion
In this short article I've shown you the basic procedure for including topics from related topics fields in the main portal search results web part. With the flexibility for rendering provided by XSLT it should be possible to create a number of interesting and useful search renderings that combine full-text search with related topic information.