原文发布于 2012 年 7 月 24 日(星期二)

(标准免责声明:博客阅读会伤害视力。为了您的用眼健康,请下载附件,其中是本文的 Word 文档版本。)

今天的标题很长,但我们要讲的内容也确实很多。SharePoint 2013 拥有很多卓越的功能,可供您真正地使用和自定义搜索结果,这是前所未有的。在本文中,我不会尝试给出所有功能的全面介绍,也不会对文中用到的组件给出大量的细节描述,因为这些都可以在他处完成。在这里我会给出搜索结果的初始设置,简要介绍各个功能,然后对使用这些功能创建一个非常酷的自定义搜索结果的完整过程进行演练,以此说明各个部分是如何协作的。

 

首先,一起来看一下在服务器场中运行 "sales reports"(销售报表)查询时得到的搜索结果(注意:下图为试用版 2,最终版本的外观可能会有所不同):

 

 

这是现成的搜索结果体验,看起来还不错。但是,既然我们已经在 SharePoint 2013 中增加了这些能够帮助您丰富终端用户搜索体验的强大功能,那就让我们为这个场景加点料吧。公司有多个部门,其中一些要负责管理部门内部的销售情况。久而久之,所有部门都使用一个标准 Excel 模板来报告他们的销售活动。此外,每个部门都有专人负责管理客户关系、报告他们的销售信息。那么,我们应如何利用 SharePoint 的这些功能,来帮助他们规范和提供有关部门及其客户的重要信息呢?我们将采取多管齐下的方式解决这一问题。

 

自定义内容类型

 

首先,我们要创建一个自定义内容类型,让每个人都能将销售报表上载到 SharePoint。先创建要用到的网站栏 – 这些是希望在搜索销售报表时出现的字段。对于我们的场景,已定义以下将要用到的网站栏:

 

网站栏名称

类型

Account Manager(客户经理)

单行文本

Direct Reports(直接下属)

数字

Sales Region(销售区域)

选择:Northamerica(北美)、EMEA、Asia(亚洲)

Top Accounts(重要客户)

单行文本

Total Accounts(客户合计)

数字

 

接下来我会创建了一个内容类型,包含所有这些网站栏。该内容类型在与 Managed Metadata Service 关联的发布中心网站创建,以便推送到服务器场中所有的订阅网站,本例即为所有 Web 应用中的所有网站。

 

在本例中,下一步是将该内容类型手动添加到各部门网站集的可用内容类型列表中,列表位于他们存储销售报表(以及其他资料)的文档库中。很明显,我们可以实现该操作的自动化,但为求简便,我手动操作。这样,第一个步骤就完成了 – 我们有了一个自定义内容类型并进行了部署,随着销售报表添加到这些文档库中,客���经理在上载并填写元数据时,只要找到销售报表就可以了。

 

托管属性

 

现在,这些销售报表已经填入网站中,我们需要在销售报表自定义网站栏创建托管属性。要在该场景下实现这一目的,与 SharePoint 2010 相比,SharePoint 2013 并没有新颖之处 – 您需要进行完全爬网来创建已爬网属性,然后创建映射至这些已爬网属性的托管属性,然后再进行一次完全爬网。我说该场景没有什么不同,是因为我们实施的是服务器场范围的解决方案。而 SharePoint 2013 确有一个很棒的功能,可以让网站集管理员标记他们的网站集、网站甚至完全爬网列表。这样,您要想在较小范围内进行这一操作时,则不必进行对企业进行完全爬网,这真的棒极了。我会另写一篇文章介绍这一功能 – 这里只是提一下,它并不适用于本例,因为我们的解决方案是针对整个服务器场的。

 

查询规则

 

这时,我们有了使用自定义内容类型的销售报表,也有了以这些销售报表元数据值填充的托管属性。接下来要做的是,确保在搜索可能包含某一销售报表的内容时,这些项目会被“注意”到。SharePoint 2013 有一项非常适用的功能,叫做“查询规则”。查询规则有三个主要组成部分:

 

  1. 条件 – 查询规则的条件决定何时启动查询。规则中可以使用许多不同的变量。我只是简单地介绍一下,但使用这些变量的可能性巨大,实际上,您会发现其中有很多已设定为现成。还有一种有趣的转换 – 如果您希望一条查询规则在每次搜索结果时都启动,只要不设置条件就好了。当然也可以反过来,设定多重条件。您或许很快就会发现,您是如何迷失在此处的可能性范围之中。可用于查询规则的条件包括:
    1. 以特定字词开头或结尾的查询
    2. 包含操作词(定义为典型动词的词,如“下载”等)的查询
    3. 包含属于托管元数据术语集的词的查询(使用这一查询可以实现一些很酷的功能)
    4. 在其他结果源,如视频结果、文档结果等中很常见的查询 – 可以是任何内容,因为结果源由您定义和创建
    5. 结果中包含常被点击的结果类型,如讨论、Excel 电子表格等
    6. 高级规则,您可以尽情使用正则表达式,将查询分为操作术语和主题术语(删除操作术语后剩下的术语)等等
  2. 操作 – 是指满足您的查询规则条件时执行的操作。此处有三个选择:
    1. 添加升级结果 – 类似于 SharePoint 2010 中的最佳匹配以及 SharePoint 2010 的 FAST Search 的可视化最佳匹配的工作原理。您可以添加将会显示在所有搜索结果顶部的新链接。可以选择以超链接或图片的形式呈现链接 – 类似于可视化最佳匹配。
    2. 添加结果块 – 通过结果块,您可执行一次额外查询,返回的结果与原始搜索结果一起呈现。之所以称为块,是因为所有结果都以块的形式一起呈现。您可让块显示在所有搜索结果的顶部,或是根据排名与其他搜索结果混在一起。一定要注意,这并不意味着两次查询间有相关排名。而是说结果块作为一个整体,与其他所有本地搜索结果一样拥有排名。点击结果块中的任意项目时,单击操作会在本地记录,而结果块作为整体会更具相关性。因此,如果块中的项目被点击多次,那么随着时间的推移,结果块在结果中的排名就会开始上升,因为单个结果不会被频繁选中,它具有更大的相关性。实际上您还可以做很多工作来配置结果块,但正如之前所说,这里不做深究。
    3. 更改查询以改变排名结果 – 顾名思义(因此该选项也较长),您可以进入并以任何方式更改请求的查询。您可添加更多的标准,删除术语,使用 XRANK 修改排名 – 这里的选择非常多。
  3. 发布 – 通过发布可以控制是否以及何时使用查询规则。例如,您要创建一组在感恩节销售之后的第二天启动的规则。在此之前您并不希望启动它们。所以您可以创建规则,但对发布进行配置,让规则处于非活动状态。也可以让规则处于活动状态,但配置为从特定日期开始,并在稍晚的某一日期结束。

好的,以上是对查询规则的“简要”介绍,那么我们应如何使用它们呢?其实,有一项现成的查询规则可以完成这一任务。实际上,在获取上面的屏幕截图时我已将该规则设为非活动状态,以便您对其影响有更好的理解。本例中,我们希望在查询销售报表时,我们部门的销售报表出现在销售报表能够出现并被人注意到。因此,进入您的“搜索”(Search) 网站集,“网站设置”(Site Settings),然后单击“查询规则”(Query Rules) 链接。在“选择源”(Select a source) 下拉列表中,单击并选择“本地报表”(Local Reports) 和“数据结果”(Data Results);您将看到一项名为“报表和数据”(Reports and Data) 的查询规则。单击并从下拉菜单中选择“查看”(View) 以查看该规则的结构。其工作原理如下:

 

  • 条件 – 该规则的条件是查询开头或结尾处包含下列单词之一:analysis、cube、dashboard、dashboards、data、database、report、reports、sales。请注意,这里既有 "reports"(报表)又有 "sales"(销售)。因此,如果有人执行 "sales reports"(销售报表)查询,将会执行该查询规则。听起来好极了 – 如果有人搜索 "sales reports",我们也希望他们看到我们部门的销售报表。作为该规则的一部分,"match"(匹配)会被指定为操作术语,而其余部分则被指定为主题术语。本例中,"reports"(报表)被指定为操作术语,而 "sales"(销售)被指定为主题术语。
  • 操作 – 该规则的操作只是运行另一个只基于主题术语的查询。因此,根据以上条件,只会针对 "sales"(销售)运行一项单独查询。这会添加一个结果块,并始终返回到所有其他结果的顶部。但是 … 它只会在“本地报表”(Local Reports) 和“数据结果”(Data Results) 源中搜索销售数据。此结果源也是现成的,实际上只返回 Excel 文档(文件扩展名为 .XLSX、XLS 等)。太好了,这样就是由查询来运行针对 Excel 文档中 "sales" 的查询。
  • 发布 – 该规则处于活动状态,没有开始日期或结束日期的限制,所以始终是启动的。

 

重新启用该查询规则后,现在查询 "sales reports" 的结果如下:

 

 

不错,我们有了一些进展 – 查询规则生效了,现在我们获得的文档是基于在结果顶部显示的自定义销售报表内容类型 – 真是太棒了!但是,依然没有显示关于文档的任何元数据,而这些元数据才是带来这一切的真正原因。

 

显示模板

 

在 SharePoint 2010 中,如果要以不同方式呈现某一特定项目,会是一个相当艰巨的过程,要进入核心结果 Web 部件并修改大量的 XSLT。您需要拥有高超的 XSLT 技术,尝试在庞大的文档中找到适当位置并插入您的自定义代码。总体而言,这种体验一点也不令人愉快。

 

在 SharePoint 2013 中 – 为音乐排队 – 我们有了显示模板,这是一项很大的改进。您不再需要对 XSLT 的虔诚信仰,而是可以直接以 HTML 的形式创建自已的自定义显示代码 – 太棒了!事实上,在本文中,我将使用 Adobe 的 Dreamweaver CS6 来创建自定义显示模板的“代码”。那么,显示模板的工作原理是怎样的呢?

 

使用显示模板,您需要追踪以下几项:

 

  1. 托管属性 – 您需要告诉模板查询时您需要检索哪些托管属性。然后就可以在您的 HTML 中使用这些属性,使用方法稍后介绍。
  2. 外部 JS 和 CSS – 如果有任何想要与显示模板一起使用的 Javascript 或 CSS 文件,您可以将它们外部化并添加到显示模板中。
  3. Inline JS – 您也可以在显示模板中使用 Inline JS。只需确保其位于显示模板中第一个 <div> 下方 – 同样将在稍后详细介绍。
  4. HTML – 这是您实际创建的 HTML,显示模板将用于呈现结果。

 

对于显示模板,我们创建的自定义销售报表内容类型中的属性将尽数出动,它们在搜索结果中的显示大致如下:

 

 

我们开始吧 – 首先,创建新的显示模板时,您几乎总会希望从现有的显示模板开始。进入您的搜索中心网站集的“网站设置”(Site Settings) 后,单击“母版页”(Master pages) 和“页面布局”(Page Layout) 链接。进入库,单击 Display Templates 文件夹,然后单击 Search 文件夹。这里包括所有现成的显示模板。您可能会看到很多文件名称相同,但后缀是 .html 或 .js。需要关注的是 .html 文件 – .js 文件是在上载 .html 文件时自动生成的。本例中,由于显示模板是针对 Excel 文件的,我就从 Item_Excel.htm 文件开始。将副本下载到本地,重命名为 SalesReport.html,然后在 Dreamweaver 中打开。

 

接下来添加托管属性。有一个名为 mso:ManagedPropertyMapping 的标记,您可以将显示模板需要的托管属性放在这个位置。我将我的放在了列表末尾,使用与其余托管属性相同的格式 – 就像这样:

 

<mso:ManagedPropertyMapping msdt:dt="string">'Title':'Title', 'Author':'Author', 'Size':'Size', 'Path':'Path', 'Description':'Description', 'LastModifiedTime':'LastModifiedTime', 'CollapsingStatus':'CollapsingStatus', 'DocId':'DocId', 'HitHighlightedSummary':'HitHighlightedSummary', 'HitHighlightedProperties':'HitHighlightedProperties', 'FileExtension':'FileExtension', 'ViewsLifeTime':'ViewsLifeTime', 'ParentLink':'ParentLink', 'ViewsRecent':'ViewsRecent', 'FileType':'FileType', 'IsContainer':'IsContainer', 'ServerRedirectedURL':'ServerRedirectedURL', 'ServerRedirectedEmbedURL':'ServerRedirectedEmbedURL', 'ServerRedirectedPreviewURL':'ServerRedirectedPreviewURL', 'AccountManager':'AccountManager', 'SalesRegion':'SalesRegion', 'TotalAccounts':'TotalAccounts', 'TopAccounts':'TopAccounts', 'DirectReports':'DirectReports', 'ContentType':'ContentType'</mso:ManagedPropertyMapping>

 

如您所见,我添加了 AccountManager、SalesRegion 等 – 为自定义内容类型创建的所有属性。然后,向下滚动至如下位置:

 

<div id="_#= $htmlEncode(itemId) =#_" name="Item" data-displaytemplate="ExcelItem" class="ms-srch-item" onmouseover="_#= ctx.CurrentItem.csr_ShowHoverPanelCallback =#_" onmouseout="_#= ctx.CurrentItem.csr_HideHoverPanelCallback =#_">

                                                                _#=ctx.RenderBody(ctx)=#_                                                     

                <div id="_#= $htmlEncode(hoverId) =#_" class="ms-srch-hover-outerContainer"></div>

</div>

 

删除外层 DIV 标记(上面以红色突出显示)之间的全部内容。现在我可以编写 HTML 了。在此之前,您应该了解三件事:

 

  1. 您可能会发现将 <style> 标记保持在显示模板的 <head> 部分最为容易。呈现显示模板时,这些样式标记将被丢弃,具体原因此处不作深究,所以最终需要复制您的样式标记并放入独立的 CSS 文件中。然而,在真正创建 HTML 时,您可以使用并修改您的样式标记,以确保它们能反映您想要的显示模板外观。
  2. 如前所述,您可以添加所谓的 Inline Javascript,这就意味着只要位置合适,可以添加 javascript 代码。显示模板的合适位置是指,代码必须位于显示模板的第一个 DIV 标记之后。同时还要位于起始标记和结束标记组(类似于 <!--#_ 和 _#-->)之间。后面我会对自定义标记进行详细解释,这里我只想说,Javascript 只有放在这些标记之间才会执行。不过非常酷的是,创建将要输出的 HTML 时,您可以使用 Inline Javascript 中定义的变量。在下一项中我将进行更多的解释。
  3. 要从您创建的 Inline Javascript 发出托管属性或的变量,它们需要位于类似于 _#= 和 =#_ 的起始标和结束标记组之间。名为 ctx.CurrentItem 的对象中的托管属性全部可用。例如,要发出 AccountManager 托管属性,我就要添加以下标记:_#= ctx.CurrentItem.AccountManager =#_。如果我有外形为 var foo = “The current Account Manager is “ + ctx.CurrentItem.AccountManager + “.”; 的 Javascript,那么要发出 "foo",就要添加标记 _#= foo =#_。这就让您可以灵活地添加或处理数据,并用于显示模板。

 

好了,现在您已经了解创建 HTML 的机制,现在的问题是我用什么来创建上面展示的显示模板;在标头标记中我添加了以下样式属性:

 

<style>

.ReportDiv

{

                float:left;

}

.ReportText

{

                font-family: Verdana, Geneva, sans-serif;

                font-size: 12px;

}

.ReportHeading

{

                font-weight: bold;

}

.LogoImg

{

                margin-top: 15px;

                width: 118px;

                height: 101px;

}

.MasterDiv

{

                float:left;

                height: 215px;

                width: 342px;

                background-repeat: no-repeat;

                background-image: url(http://sps/sites/search/PublishingImages/SalesReportBackground.PNG);

                padding: 15px;

}

.DetailsContainer

{

                background-color:#CCC;

}

</style>

 

用作客户经理详细信息背景的图片已经上载到我的网站中,这是此处需要注意的重点;其他问题都是相当清楚的。同样,将此样式标记放在 <head> 部分,在 Dreamweaver 中进行设计时,就可以清楚地看到布局的样子。

接下来,让我们看一下用于创建显示模板的 HTML 本身:

            <div>

                <div class="ReportDiv">

                                <img class="LogoImg" src="http://sps/sites/search/PublishingImages/SalesReportLogo.PNG" />

                </div>

                <div class="MasterDiv">

                   

                    <!-- Title and link to item -->

                    <a href="_#= ctx.CurrentItem.Path =#_" class="ReportText">_#= ctx.CurrentItem.Title =#_</a>

                    <br/><br/>

 

                    <!-- Account Manager -->

                    <span class="ReportHeading ReportText">

                      Account Manager:

                    </span>

                    <span class="ReportText">

                      _#= ctx.CurrentItem.AccountManager =#_

                    </span><br/>

                   

                    <!-- Sales Region -->

                    <span class="ReportHeading ReportText">

                      Sales Region:

                    </span>

                    <span class="ReportText">

                      _#= ctx.CurrentItem.SalesRegion =#_

                    </span><br/>

                   

                    <!-- Total Accounts -->

                    <span class="ReportHeading ReportText">

                      Total Accounts:

                    </span>

                    <span class="ReportText">

                      _#= ctx.CurrentItem.TotalAccounts =#_

                    </span><br/>

                   

                    <!-- Top Accounts -->

                    <span class="ReportHeading ReportText">

                      Top Accounts:

                    </span>

                    <span class="ReportText">

                      _#= ctx.CurrentItem.TopAccounts =#_

                    </span><br/>

                   

                    <!-- Direct Reports -->

                    <span class="ReportHeading ReportText">

                      Direct Reports:

                    </span>

                    <span class="ReportText">

                      _#= ctx.CurrentItem.DirectReports =#_

                    </span><br/>

                   

                    <!--  Hit Highlighted Text -->

                    <br/>

                    <span class="ReportHeading ReportText">

                                Details:

                    </span>

                    <br/>

                    <span class="DetailsContainer ReportText">

                                _#= Srch.U.processHHXML(ctx.CurrentItem.HitHighlightedSummary) =#_

                    </span>

                </div>

            </div>        

 

我将跳过对该内容格式功能的讨论,将重点放在数据上。您可以看到其中插入托管属性的位置(使用 _#= 和 =#_ 标记)。您会发现这是纯粹的标记替换,甚至可以在上面的 <a> href 属性中直接使用(这与 XSLT 的做法截然相反,用 XSLT 要复杂得多)。其余的字段只是插入相应的 DIV 或 SPAN 格式标记。此处出现的特殊情况是 HitHighlightedSummary,它使用的是搜索自带的内置处理组件。此时我并没有组件、方法及其功能的完整列表,但我添加是因为如果您不使用它,您的摘要就不会突出显示。因此,请确保使用此方法以达到这一目的。

 

现在一切已经正常工作了,但还需要对标记再做处理。我将 <style> 标记之间的所有内容复制下来,并放入一个名为 SalesReport.css 的新 CSS 文档中。在母版页样式库的 /Display Templates/Search 文件夹下,我创建了另一个名为 styles 的文件夹。我将 SalesReport.css 文件上载到该目录。现在,要在显示模板中使用它,必须添加新的脚本标记。它应该位于 <body> 标记之下,第一个 <div> 标记之上。我使用一个名为 $includeCSS 的 SharePoint Jjavascript 功能来下载我的 CSS 文件以供显示模板使用。因此,起始标记的形式如下:

 

<body>

<script>

                                $includeCSS(this.url, "./styles/SalesReport.css");

</script>

 

<div id="Item_SalesReport">

 

很好,现在我们的代码就完成了,但要怎么使用我们的自定义显示模板呢?

 

结果类型

结果类型是指根据一组规则,调用显示模板的方法。规则的使用非常简单 – 您可以针对特定的预定义内容类型启动,如电子邮件、PDF、Word 文档、SharePoint Wiki 等。除此之外,也可以仅在查询特定结果源时使用它们。最后,您还可以选择托管属性作为规则标准,进行常见的比较。例如,如果您想对您的副总裁使用不同的显示类型,就可以只在 AccountManager 字段包含 "Vice President"(副总裁)时才启用某一结果类型规则。本例中,我们希望仅在内容类型等于 "Sales Report" 时才启用我们的结果类型。因此我们为结果类型添加一个条件,规定 ContentType 等于 "Sales Report"。

 

 

如您所见,我们甚至可以添加多个匹配值。我们也可以添加多个属性,以 AND 将其加一起。对于这种场景,我们只需要 ContentType。一旦我们定义了条件,就可以配置规则的操作了。对于结果类型,操作只是一个带有所有可用显示模板的下拉列表。我要做的只是从下拉列表中选取 Sales Report 显示模板,然后单击“保存”(Save) 按钮以创建结果类型。同样,如果您不确定如何创建结果类型,那就看一看 SharePoint 中所有的现成结果类型。通过观察现有的结果类型,您能想到很多关于新结果类型的好点子。

 

组合在一起

现在,所有内容已各就各位 – 一个捕获我们想要的元数据的自定义内容类型、一些提取元数据并放入索引的托管属性、确保有人查询 "Sales Report" 时我们的销售报表内容会弹出到列表顶部的查询规则、以绝不类似典型搜索结果的真正独特且有用的格式显示捕获的元数据的自定义显示模板,以及确保当搜索结果中返回自定义内容类型时使用我们的显示模板的结果类型。下图为完成后的最终结果:

 

 

至此,我们对 SharePoint 2013 中用于呈现搜索结果的一些非常酷的功能的介绍就结束了。希望您能用到这些强大的功能,并从中发现更多有用且有趣的使用方法。

这是一篇本地化的博客文章。 请访问 Using Query Rules, Result Types and Display Templates for a Custom Search Sales Report in SharePoint 2013 以查看原文