在Notes应用程序中添加 OmniFind 搜索功能

现在,您能够向一个常规的由 Notes 客户机访问的 Lotus® Notes® 数据库应用程序添加 IBM® OmniFind™ 搜索功能。特别是您将在本文学习到如何在 LotusScript. 中调用 IBM 的 Java™ 搜索与索引 API(SIAPI)。除了向您说明如何以常规文本字段显示搜索结果,本文还阐述了如何在 Notes 客户机上以 HTML 表单形式显示搜索结果,这会大大提高终端用户搜索界面的外观与感受。

简介

IBM OmniFind 企业版是一个企业级全文搜索产品,旨在提供具有广泛数据源支持的高级性能、范围和结果质量。由于对 Lotus 的支持,OmniFind 能够对 Lotus Notes 数据库、Lotus QuickPlace® 和 Lotus Domino® 文档管理器进行安全索引和搜索。

OmniFind 超越了当前 Domino 所提供的搜索,从以下几个重要的方面增强了应用程序的搜索功能。首先,OmniFind 将搜索范围扩大到 Domino 之外,包括 Web 、文件系统、关系型数据库以及其他邮件和文件管理系统。 OmniFind 的高级搜索特性丰富了终端用户的搜索体验,这些特性包括语法检查、动态摘要、快速链接、站点折叠等。尤为重要的是,OmniFind 通过接管全文本检索和搜索操作,可以提高 Domino 服务器性能。 OmniFind 做到了真正的企业级,能够支持的文档数高达 2 千万。

或许您已经拥有 OmniFind 并且发现设置索引、启动搜索是多么简单快速,您也可能已经察觉到 OmniFind 所提供的客户端搜索应用程序是基于 J2EE 的,倾向于运行在 J2EE 应用服务器环境下,如 IBM 的 WebSphere ®。 如果您的客户群是通过 Web 浏览器访问,这固然比较合适,但是也许您的终端客户仅依赖 Notes 客户机访问 Domino,在这种情况下,请继续往下读,找到向常规 Lotus Notes 应用程序添加搜索功能的方法。

OmniFind 搜索应用程序设计示例

该设计的一个重要概念就是 OmniFind 相对于 Domino 的关系。OmniFind 所运行的进程空间独立于 Domino。 因此,最常见的建议就是将 OmniFind 运行在一个专用的服务器上。这样做是为了支持可能有的大量将被索引的企业文档,也有助于将 Domino 从全文本检索和搜索负荷中解脱出来。服务器与 Notes 客户机拓扑结构如图 1 所示。


图 1. OmniFind Notes 应用程序拓扑结构
OmniFind Notes 应用程序拓扑结构

OmniFind 安装在一个独立的服务器上,被配置为在指定 Domino 域中爬行并索引一个或多个 Notes 数据库。通过 OmniFind 的搜索索引,可以搜索到这些数据库。图 1 的左下角说明了上述情况。需要注意的一点是,用户并不是在搜索原始的 Notes 内容,而是对 OmniFind 搜索索引进行搜索,这些索引可能包括企业的其他爬行过的内容(例如, Web 、文件系统等)。

如图 1 左上角所示,本 OmniFind 搜索应用程序被设计为一个常规 Notes 数据库,命名为 OmniFind.nsf。 OmniFind.nsf 由两个表单构成:

  • 第一个表单使您指明使用哪个 OmniFind 系统进行搜索(对此,后有详述)。
  • 第二个表单是实际的搜索表单,用来提交查询并显示搜索结果。搜索表单附有负责调用 SIAPI 的 LotusScript,SIAPI 按照第一个表单所设定的配置与 OmniFind 通信。

图 2 是该 OmniFind 搜索应用程序的一张屏幕截图。左侧的表格内容窗格提供了三个选项。 OmniFind Settings选项将向您显示图 3 所示的配置表单。这里您要提供 OmniFind 服务器的主机与端口。如果在 OmniFind 服务器上启用了安全性则还要提供用户 Id 和密码,此外还需要一个 Application Id 和 Collection Id。为简单起见,本设计方案仅搜索由指派的 Collection Id 所表示的一个 OmniFind 集合。单个 OmniFind 集合可能包含来自多个 Notes 数据库和其他数据源的文档。本设计的一个一般扩展就是允许用户从集合列表中选择他们想搜索的多个集合。表单提供了一个 Test Connection 按钮,用来使用提供的设置与 OmniFind 服务器通信。无论连接成功与否,都会显示一条状态消息。


图 2. OmniFind Notes 应用程序
OmniFind Notes 应用程序

Saved Searches 选项展示了曾经执行过的查询及其结果列表。对于任何典型的搜索应用程序,这都是一个常用特性,Notes 的内部设计轻松实现了该特性。因为搜索表单无非就是一个 Lotus Notes 表单,可以把它的一个实例作为文档存入 OmniFind.nsf 数据库。对于这些搜索表单,由一个数据库视图列出查询发起者、查询提交的日期和时间以及查询所包括的关键词。如果 OmniFind.nsf 数据库位于 Domino 服务器,则有可能与其他用户共享这些被保存的查询,从而完全消除再次执行这些搜索的必要性。

表格内容窗格中的 Start Searching 选项向您展示搜索表单。图 2 右下角展示了一个搜索表单实例。表单包括两个部分。顶部提供了一个编辑框,用户在此输入搜索词,编辑框后是一个 search 按钮,用来执行搜索。表单中横线下的表单下半部分用来显示搜索结果。每页显示十条结果,有向前和向后按钮用来在不同结果页面间导航。


图 3. OmniFind 设置表单
OmniFind 设置表单
注意:本应用程序在 Lotus Notes V6.0 上进行过测试。

安装 OmniFind 示例 Notes 应用程序

这里假定已经在一台独立服务器上安装好 OmniFind 产品,并为其配置了一个可搜索集合(索引)。该集合可以包含来自任何受支持来源的文档。不过,本 OmniFind 示例应用程序当前仅被设计用来显示图标,用以表示来自 Lotus Notes 和文件系统文档的结果。这仅限于用来说明所显示的结果是何种类型。您可以从容地添加更多来源类型图标。

OmniFind 示例搜索应用程序的安装分为两个步骤。

  1. 从本文 下载 一节下载 OmniFind.nsf 数据库,并将其拷贝到您的 Domino 数据目录中。
  2. 将 OmniFind /lib 目录的 esapi.jar、siapi.jar 文件复制到 /jvm/ext 目录。

OmniFind 示例应用程序使用 LotusScript. 调用 IBM 搜索和索引 API(SIAPI)。为支持它,esapi.jar 和 siapi.jar 文件是必需的,而且必须在 jvm/ext 目录中可被 Domino 访问。

安装的验证很简单,就是用 Notes 客户机访问 OmniFind.nsf 数据库,填好 OmniFind 设置表单,使用搜索表单发布搜索。在设置表单上点击 Test Connection 按钮来检验设置是否正确是一个好主意。 常见的错误是提供了错误的集合 Id、主机或端口。默认的 ApplicationId 应当设置为 Default

使用 Java 语言编写的简单的 SIAPI 示例

在查看如何从 LotusScript. 调用 SIAPI 之前,最好先回顾一个用 Java 语言写的使用 SIAPI 的简单搜索示例。这样您可以了解如何通过 SIAPI 调用发出搜索。一旦您熟悉了这些需求,剩下的就只是用 LotusScript. 到 Java 接口在 LotusScript. 里执行同样的调用而已。清单 1 举例说明了一个简短的 SIAPI 搜索代码示例。


清单 1. 使用 Java 编写的 SIAPI 示例
                
// create a valid Application ID that will be used
// by the Search Node to authorize access to the collection
ApplicationInfo appinfo = factory.createApplicationInfo(applicationName);
appinfo.setPassword(applicationPassword);

// create a new Properties object.
Properties config = new Properties();
config.setProperty("hostname", "OmniFindHostName");
config.setProperty("port", "80");
config.setProperty("timeout", "60");
config.setProperty("username", "websphereUser");
config.setProperty("password", "webspherePassword");

// obtain the OmniFind specific SIAPI Search factory implementation
SearchFactory factory = (SearchFactory) 	
	Class.forName("com.ibm.es.api.search.RemoteSearchFactory").newInstance();

// obtain the Search Service implementation
SearchService searchService = factory.getSearchService(config);

// obtain a Searchable object to the specified collection ID
Searchable searchable = null;
try { searchable = searchService.getSearchable(appinfo, collectionId);
} catch (SiapiException e) {return;}

// create a new Query object using the specified query string
Query q = factory.createQuery("search terms go here");

// execute the search. A ResultSet object will be returned
ResultSet rset = null;
try { rset = searchable.search(q);
} catch (SiapiException e) { return; }

Result r[] = rset.getResults();
for (int k = 0; k < r.length; k++) {
     System.out.println("Result " + k + ": " + r[k].getDocumentID());
}
      

ApplicationInfo 对象首先被创建,用来向 OmniFind 标识您的程序。OmniFind 管理员能够为您的程序指派全部或部分集合,进行授权搜索。

接着创建 Properties 对象,包含与 OmniFind 服务器的连接信息。该 Properties 对象 用于 getSearchService 调用,得到与 OmniFind 服务的实际连接。注意要得到 OmniFind 实现,必须先实例化 OmniFind 搜索工厂。

一旦有了 SearchService 对象,您就能够得到一个或多个可搜索对象,每个对象都关联着一个可被搜索的授权集合。本例中我们仅得到一个可搜索对象。

接着我们用给定的搜索短语创建一个查询对象。在调用 createQuery 时您可以使用自己的查询表达式。

此时我们准备使用可搜索对象的 search 方法发布搜索,并将搜索传递到此前所创建的查询对象。该请求将执行搜索并返回一个 SIAPI 结果集对象。调用 getResults,多个结果将以数组形式返回。对单个结果的不同属性有许多种访问方法,如得到文档 Id、标题、与/或 URL。

本文后面部分将详细描述 OmniFind.nsf 中所用到的 LotusScript。在学习了如何从 LotusScript. 调用 SIAPI 的基础知识后,您将可以写出您自己的高级 OmniFind Notes 搜索应用程序。

从 LotusScript. 调用 SIAPI

当用户在搜索表单输入查询表达式并单击搜索按钮后,RunSearch LotusScript. 库得到控制权。 RunSearch 的功能是负责调用 SIAPI ,发布搜索并处理结果。


图 4. 使用 Domino Designer 编辑 LotusScript
使用 Domino Designer 编辑 Lotus.

从这里开始,假定读者已经熟悉 LotusScript. 并且知道如何使用 Domino Designer 修改 LotusScript。图 4 举例说明了在 Domino Designer 中打开的 OmniFind.nsf 。表单类别展开后显示两个表单,分别为 searchsettingsShared Code/Script. Libraries 类别也展开显示两个函数,分别为 ReplaceSubstringRunSearchReplaceSubstring 是一个工具函数,本文不做阐述,但您可以自己研究。最为重要的是右侧面板展示的 RunSearch 函数,对于它要做更加详细的讨论:

RunSearch LotusScript. 函数

RunSearch 函数开头处定义了它所用到的绝大多数变量。

除 SiapiResults 被定义为 Variant 外,下面所有的 SIAPI 对象都遵守 LotusScript. 到 Java 接口,被定义为 JavaClass、 JavaMethod 或 JavaObjects 中的一种。


清单 2. SIAPI 对象定义
                
	Dim SiapiImplClass As JavaClass 
	Dim SiapiFactoryObject As JavaObject  
	Dim SiapiImplMethod As JavaMethod  
	Dim SiapiAppInfoObject As JavaObject 
	Dim SiapiSearchServiceObject As JavaObject 
	Dim SiapiSearchableObject As JavaObject 
	Dim SiapiQueryObject As JavaObject 
	Dim SiapiResultSetObject As JavaObject 
	Dim SiapiResultObject As JavaObject 
	Dim SiapiResults As Variant
	

还需要如下一些原生 Java 对象:


清单 3. Java 对象定义
                
	Dim JavaPropertiesClass As JavaClass 
	Dim JavaPropertiesObject As JavaObject 
	Dim JavaPropertiesMethod As JavaMethod 
	Dim JavaDate As JavaObject

其余的变量定义支持 Notes 文档操作和一般字符串变量。

按照顺序,首先要读取设置文档,得到当前的 OmniFind 连接信息。以后要利用该信息创建 Java Properties 对象。注意该逻辑动作会在初始化时执行一次。


清单 4. 检索 OmniFind 设置
                	
	Set curdb = notesSession.CurrentDatabase
	Set view=curdb.GetView("Settings")
	Set doc = view.GetDocumentByKey("Settings", True) 
	ApplicationID = doc.GetItemValue("ApplicationID") (0)
	User = doc.GetItemValue("User") (0)
	Password = doc.GetItemValue("Password") (0)	
	Host = doc.GetItemValue("Host") (0)
	Port = doc.GetItemValue("Port") (0)
	CollectionID = doc.GetItemValue("CollectionID") (0)

接下来的语句非常重要,负责在 LotusScript. 和 JVM 之间建立一个 Java 会话。


清单 5. 建立 Java 会话
                	
	Set javaSession = New JavaSession()

同 SIAPI Java 例子相近,SIAPI 的第一步是为 OmniFind 实现得到工厂对象。为此,您必须首先从 Java 会话得到 SiapiSearchImpl 类,从该类得到 SearchFactory 方法,然后调用该方法得到如下所示的实际工厂对象:


清单 6. 得到 OmniFind 工厂对象
                
Set SiapiImplClass = 	javaSession.GetClass("com/ibm/siapi/search/SiapiSearchImpl") 
Set SiapiImplMethod = 	SiapiImplClass.GetMethod
	("createSearchFactory","(Ljava/lang/String	;)
	Lcom/ibm/siapi/search/SearchFactory;")  
Set SiapiFactoryObject = 	SiapiImplMethod.invoke
	(,"com.ibm.es.api.search.RemoteSearchFactory")  

获得工厂对象后,您就能够创建 OmniFind Application Info 对象,它将控制该应用程序能够搜索的集合。您应当从 OmniFind 管理员处得到适当的 Application Id。默认值是 “Default”。


清单 7. 得到一个 application info 对象
                
Set SiapiAppInfoObject = 	SiapiFactoryObject.createApplicationInfo(ApplicationID)

接着,您要做的是创建一个 Java Properties 对象,并用从设置文档获得的适当的 OmniFind 连接信息初始化该对象。与用来获得 Factory 对象的步骤相似,您必须向 Java 会话请求类并从该类得到 setProperty 方法。仅当 OmniFind 服务器启用了全局安全性时,才需要用到用户名和密码属性。下面是必需的一些调用:


清单 8. 创建 Java 属性对象
                
Set JavaPropertiesClass = javaSession.GetClass("java/util/Properties")
Set JavaPropertiesObject = JavaPropertiesClass.CreateObject()
Set JavaPropertiesMethod = 	JavaPropertiesClass.GetMethod
	("setProperty","(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;")
Call JavaPropertiesMethod.invoke(JavaPropertiesObject,"hostname",Host)
Call JavaPropertiesMethod.invoke(JavaPropertiesObject,"port",Port)
Call JavaPropertiesMethod.invoke(JavaPropertiesObject,"timeout","60")
Call JavaPropertiesMethod.invoke(JavaPropertiesObject,"username",User)
Call JavaPropertiesMethod.invoke(JavaPropertiesObject,"password",Password)

现在,使用上面定义的连接属性可以为 OmniFind 服务器获得一个搜索服务,并根据赋予的 Application Id 的权限,获得待搜索的特定集合中的可搜索对象。


清单 9. 获得 OmniFind 可搜索对象
                
Set SiapiSearchServiceObject = 	SiapiFactoryObject.getSearchService(JavaPropertiesObject)
Set SiapiSearchableObject = 	SiapiSearchServiceObject.getSearchable
	(SiapiAppInfoObject,CollectionID)
 

我们几乎已经为发布搜索做好了全部准备。但在此之前,我们必须按照搜索字符串和用户提供的其他参数建立一个 SIAPI Query 对象。我用标准的 Notes 文档方法从当前搜索表单得到该信息。下面描述了 SIAPI 查询对象的创建及其参数设置。


清单 10. 创建 SIAPI 查询对象
                
Set SiapiQueryObject = SiapiFactoryObject.createQuery(searchExpression)
Call SiapiQueryObject.setQueryLanguage("en_US")
resultStart = (pgSize * pageNum) - pgSize
Call SiapiQueryObject.setRequestedResultRange(resultStart,pgSize)	

OmniFind 允许您一次得到一页结果,您可以定义一页包含多少结果。您所希望的页面由其起始结果编号表示。举例而言,若每页 10 个结果,可以使用起始结果编号 20 (0-9= 第一页,10-19= 第二页,20-29= 第三页,依此类推)来获取第三页。

可搜索对象的 search 方法执行该搜索并返回一个 SIAPI 结果集对象,如下所示:


清单 11. 发布搜索
                
Set SiapiResultSetObject = SiapiSearchableObject.search(SiapiQueryObject)

处理搜索结果

下面是 RunSearch 函数的部分代码,没有上下文显示,目的是示范如何使用 SIAPI 访问结果并从每个结果提取出合适的信息。一旦您将结果信息提取到标准 LotusScript. String 变量,您就应该能够用您所熟悉的标准 Notes 功能格式化并显示搜索结果了。


清单 12. 处理搜索结果
                

numResults = SiapiResultSetObject.getAvailableNumberOfResults()	

SiapiResults = SiapiResultSetObject.getResults()
		
Forall vResult  In SiapiResults
			
	Set SiapiResultObject = vResult
			
	resultScore = SiapiResultObject.getScore()
	resultTitle = SiapiResultObject.getTitle()
	resultDesc = SiapiResultObject.getDescription()
	resultURL = SiapiResultObject.getDocumentID()
	resultSource = SiapiResultObject.getDocumentSource()
	Set JavaDate = SiapiResultObject.getDate()
	resultDate = JavaDate.toLocaleString()	

End Forall 

请参阅 OmniFind Programming Guide ,了解更多 SIAPI Result 对象可用的方法。

以 HTML 格式显示结果

本文的后面部分简要描述了 RunSearch 函数中用于以 HTML 格式显示搜索结果的技术。将结果格式化为 HTML 格式并不依赖于 SIAPI 或 OmniFind,而是一个显示选择问题。 HTML 似乎在表示上具备更大的灵活性(比如在动态摘要中高亮显示查询关键词),而且也更接近于受支持的 OmniFind 示例 Web 应用程序所提供的样式。

这种方法就是构建一个字符串,包含了完整的所要显示的 HTML 语句。构建后,该字符串以 Notes 流形式写出到搜索表单的 “results” 字段。实际的流是以一种 multipart mime 文档形式写出, mime 类型设为 text,编码设为 none。

此 mime 文档的第一部分包含实际的 HTML 字符串。后面两部分包含为 HTML 引用的图标的 GIF 图像。实际的 GIF 图像由 RunSearch 函数的 Initialize 段定义。

结束语

本文阐述了如何向一个常规的由 Notes 客户机访问的 Lotus Notes 数据库应用程序添加 OmniFind 搜索功能。特别是介绍了如何在 LotusScript. 中调用 IBM 的 Java 搜索与索引 API(SIAPI)。除了向读者说明如何以常规文本字段显示搜索结果,本文还阐述了如何在 Notes 客户机上以 HTML 表单形式显示搜索结果,这会大大提高终端用户搜索界面的外观与感受。

拥有了这些基础知识,现在您将能够使用 OmniFind 搜索功能提升 Notes 应用程序,超越当今 Domino 所提供的搜索功能。使用 OmniFind 的优势在于:

  • OmniFind 将搜索范围扩大到 Domino 之外,包括 Web、文件系统、关系型数据库以及其他邮件和文件管理系统。
  • OmniFind 的高级搜索特性丰富了终端用户的搜索体验。
  • 尤为重要的是, OmniFind 通过接管全文检索和搜索操作,可以提高 Domino 服务器性能。
  • 此外,OmniFind 做到了真正的企业级,能够支持的文档数高达 2 千万。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/14751907/viewspace-417697/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/14751907/viewspace-417697/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值