编写 SOSL 查询
学习目标
完成本单元后,您将能够:
- 了解 SOSL 与其他全文搜索方案的区别。
- 认识 SOSL 基础语法。
- 描述 SOSL 和 SOQL 之间的区别。
- 编写一条 SOSL 查询,搜索多个 sObjects。
什么是 SOSL?
上一个单元向您介绍了 SOQL,您学习了如何用它在 sObjects 及其相关表格中查询数据。要想跨多个 sObjects 执行基于文本的查询,您可以使用 SOSL (Salesforce Object Search Language),这是 Salesforce 的全文搜索方案。
作为 .NET 开发人员,您可能已经熟悉 Microsoft SQL Server (MS FTS) 提供的全文搜索功能。您可能还熟悉一个称作 Lucene.Net 的热门搜索引擎库,是从原始的 Java 版本移植到 C# 的。
既是好消息,也是坏消息,SOSL 有别于那些全文搜索方案。最大的区别在于设置和维护索引有什么要求。Salesforce 采用开源搜索和索引引擎 Lucene 来赋能 SOSL,不过已经装好了,所以您无需安装和配置任何东西。您也不用负责维护索引。事实上,大部分情况下,对于如何使用搜索索引,您没有多大的控制能力,这是好事,因为这表示写 SOSL 查询很容易。
不过,作为 .NET 开发人员,您热爱微调、优化您的代码。所以听说对配置和索引几乎没有控制能力,您可能感觉有点不舒服。我们请您放心,即使您的控制能力减弱了,您还是可以做一些事情来改进查询性能,包括 SOSL 和 SOQL 查询。我们稍后详细介绍这些方法,下面我们先讨论 SOSL 语法有何不同。
编写 SOSL 查询
如果您熟悉 MS FTS,您知道需要编写 SELECT 查询,用到 CONTAINS 或 FREETEXT 语句。这个强大的 CONTAINS 搜索,有许多变体,使您可以进行准确或模糊匹配搜索,以及搜索与另一个词接近的词。
SOSL 采用更简单的搜索语法,不使用 SOQL SELECT 关键词,而是用 FIND 关键词。一条基本的查询如下所示:
FIND {"grand*"} IN ALL FIELDS RETURNING Account(Name), Contact(LastName, FirstName, Email)
我们可以把它细分为三个部分。
带搜索词的 FIND 子句
FIND 子句是必不可少的。它使 SOSL 搜索成为唯一的。FIND 后面跟的是您在查找的任何搜索词,可以是一个词或短语。在这个例子中,它是“grand”这个词。您还可以包含通配符,我们的例子中用到了,比如这两个:
* matches zero or more characters at the middle or end of the search term
?matches only one character at the middle or end of the search term
我们将在下一单元中详细探讨通配符。不过,要注意可以在搜索词的中间和末尾都使用通配符,不表示您应该这么做。事实上,这是最好的做法,却不是个好主意,因为会严重影响查询性能。
IN 子句
使用 IN 子句来指定一个搜索组。它告诉 Salesforce 去搜索哪些字段。但是这里我们有一件很重要的事情提醒您注意,所以请多担待。
在上述例子中,我们指定了 ALL FIELDS(所有字段)。有人可能会从字面意思来理解,认为将搜索所有字段,但是视您在 RETURNING 子句中指定了哪个对象而定,只包含部分基于文本的字段。您怎么看?
刚才说了,请多担待。您可以看出,如果您返回的对象是文章、文档、摘要评论、摘要项目、文件、产品或解决方案,那么会搜索所有字段,因为这些是您希望搜索所有字段的对象类型。
但是如果您在搜索大多数标准或自定义对象,其中包含各类疯狂的非文本字段,那么只通过名称、电子邮件、电话和侧栏字段来搜索是明智的选择。顺便说一下,这是默认的模式。
所以可以这么说,您应该只搜索名称字段,而不是指定 ALL FIELDS(所有字段)。然后您会用到 NAME FIELDS(名称字段)。要想只搜索电话字段,请使用 PHONE FIELDS(电话字段)。想看看如何操作?
RETURNING 子句
您用 RETURNING 子句来指定返回什么数据,搜索什么对象。在上述例子中,我们返回了客户的名称字段以及联系人的姓、名和电子邮件字段。搜索查询两个对象的所有可搜索字段,但是返回的结果只包含圆括号里的那些字段。
如果您指定某个对象名称,圆括号里没有字段名称,那么如果找到了匹配的记录,搜索只返回那个对象的 ID。
SOSL 语法还有其他可选的子句,您可能会感兴趣,请参考官方文档了解更多知识。
好了,所以现在您想知道就模糊匹配而言,与其他全文搜索引擎相比 SOSL 表现如何。除了 SOQL 查询中可以使用的 LIKE 关键词和 SOSL 查询中可以使用的通配符之外,Salesforce 只提供同义词搜索来搜索昵称。
SOQL 还是 SOSL?
您用哪个?我敢肯定您不会因为听到这个而惊讶:这取决于您想干什么。
如果您需要来自一个对象的数据并且您确切地知道那个对象的条件,您很有可能想用 SOQL。事实上,您的大部分查询很可能将在 SOQL 中。
当您不知道您的数据所存在的确切字段和对象,但是需要搜索多个对象时,SOSL 最有用。当那些对象没有关联时尤其如此,因为 SOQL 只对相关对象起作用。
执行 SOSL 搜索
既然您已经知道为什么以及如何使用 SOSL 搜索,那我们就继续,试着编写一个吧。
您不只有一种方法来执行 SOSL 搜索,不过目前我们将关注最容易的一种,用 Developer Console 中的 Query Editor(查询编辑器)。您可能还记得关于 SOQL 的上一个单元中提到过这个。
先决条件
运行 SOSL 搜索之前,我们需要把数据添加到开发组织中。首先,我们将创建一篇样本文档,可以把它上传到我们的开发组织。
- 在记事本或任何文本编辑器中,创建一个文件并且输入下述文本:
First quarter figures were better than expected for new employee Joseph Smith.
- 把该文件保存到本地,命名为 TestDocument.txt。
- 在 Developer Edtion 组织中的“文件”选项卡中,单击上载文件。
- 找到您保存 TestDocument.txt 文件的位置,单击打开。
- 单击完成。
我们还需要把数据添加到一些标准对象中。
- 从“设置”菜单中,选择 Developer Console 打开 Developer Console。
- 在 Developer Console 中,单击 Debug(调试) > Open Execute Anonymous Window(打开执行匿名窗口)。
- 删除现有代码,插入以下片段:
// Add Account and related Contact Account acct = new Account( Name='Test Account', Phone='(225)555-8989', NumberOfEmployees=10, BillingCity='Baton Rouge'); insert acct; // Get the Id of the Inserted Account ID acctID = acct.ID; // Add a contact to the Account.Contact con = new Contact( FirstName='Joseph', LastName='Smith', Phone='(225)555-8787', Email='jsmith@testaccount.com', AccountId=acctID); insert con;
- 单击执行。
使用 Developer Console
既然我们已经有了可供搜索的样本数据,现在我们可以用查询编辑器来执行一个新的 SOSL 搜索了。
- 在 Developer Console 中,单击底部窗格中的 Query Editor(查询编辑器)选项卡。
- 删除现有代码,插入以下片段:
FIND {joey} IN ALL FIELDS RETURNING Account(Name), Contact(LastName, FirstName), ContentVersion(Title)
这里您注意到的第一个东西是在之前的例子中包围搜索词的单引号被花括弧取代了。当 SOSL 搜索在查询编辑器中完成时,我们必须使用花括弧而不是引号。如果搜索是在 Apex 代码中完成的,您将使用单引号。还会注意到搜索词是“joey”这个词,已知它是 Joseph 的昵称(我们在搜索的实际名字是 Joseph)。
- 单击执行。搜索结果只显示一个选项卡。您插入的联系人列在联系人选项卡下面,因为能够根据 Winter ’16 提供的昵称功能找到匹配项。但是您上传的 TestDocument 没有列出来,因为昵称搜索只适用于客户、联系人、潜在客户和用户对象。我们来修改我们的测试,然后得到所有结果。
- 将查询编辑器中的现有代码替换为以下内容:
FIND {jos*} IN ALL FIELDS RETURNING Account(Name), Contact(LastName, FirstName), ContentVersion(Title)
- 单击执行。
- 您的搜索结果现在显示两个选项卡。Document(文档)选项卡显示您上传的文档名称。请注意我们使用了通配符搜索来返回我们期望的所有结果。
了解详细信息
SOSL 搜索可能由于限制而找不到所有匹配的结果。记住,Salesforce 是一个多租户环境。如果允许每个客户都最大程度利用资源,那么整个系统将很快瘫痪。超过 20,000 个字符的搜索将耗尽整个系统。因此,在 SOSL 中搜索是有限制的,跟在 SOQL 中一样。下一步我们将学习如何优化搜索查询。