您的位置:首页 > 其它

全文检索知识库系统方案 (一)

2007-08-14 14:56 211 查看
题记:前段时间做了一个全文检索的知识库系统构建方案的调研,在此分享。

调研方案范围
调研目的在于找到一个在功能和性能上都比较优秀的全文检索的知识库系统实现方案;在调研过程中优先考虑如何实现全文本检索功能,结合考虑系统的功能、性能、以及构建完整系统的效率。
构建全文检索的知识库系统有多种行之有效的方案,主要有以下三种实现思路:
方案A 使用支持全文检索功能的数据库,构建大型文本管理数据库系统,从文件管理数据库出发设计知识库系统;
方案B 使用全文搜索引擎实现全文本检索功能,以此开始设计知识库系统;
方案C 使用WIKI构建知识库系统。
以下分别介绍。

1 全文检索数据库方案
1.1 Oracle Text介绍
支持全文检索的数据库以建立和维护索引的方式对存储在数据库表中的大型文本系统执行有效率的文本搜索。
知识库系统中全文搜索的对象主要是表达知识信息的文章,典型的搜索应用可能是查找出标题或者内容中含有某个搜索项的所有文章。把知识库中的文章存储在按照标题、内容等文本字段建立起来的数据库表中,实现知识库系统中的全文查找也就同数据库中的全文检索功能等同起来了。
Oracle实现全文检索的的组件在Oracle9i中称为Oracle Text。Oracle Text的体系结构如下图, 在本次调研所关注的范围里,这个体系结构的中心是为存储在数据库中的文章的标题、内容等字段信息建立索引。



[align=center] 图一 Oracle Text体系结构 [/align]
1.2 DEMO - 使用Oracle数据库实现中文全文检索
目标:确认Oracle Text支持中文全文检索功能、总结操作过程,并探求更好的性能。(demo基于Oracle9.02个人版,企业版和标准版应该得到同样的结果。)
这里介绍主要的过程:
步骤1 确保数据库的一些配置项
(1)检查数据库是否安装了Oracle Text组件(Oracle9i默认安装)
检查数据库是否具有CTXSYS用户和CTXAPP角色;
如果没有则运行$ORACLE_HOME/bin/dbassist, 选择'modify database', 然后在选择数据库功能时将jserver和intermedia都选中;
(2) 检查服务器是否有对PLSExtProc服务的监听
Windows Shell命令窗口下执行lsnrctl status,在打印信息中通常有
PLSExtProc has 1 service handler(s)
这样一段即表明外部调用功能打开; 否则需要修改$ORACLE_HOME/network/admin/listener.ora以打开该功能;
步骤2 创建数据库knowledge并建立一个ctxtest用户
(1)创建数据库knowledge
(2)在数据库knowledge下建立ctxtest用户
CREATE USER ctxtest IDENTIFIED BY ctxtest;
(3)赋予ctxtest用户connect、ctxapp、resource角色
GRANT CONNECT, CTXAPP, RESOURCE TO ctxtest;
步骤3 进行数据库设计并建表
(1)使用PowerDesigner为知识库系统建立一个大致的概念模型如下,导出物理视图并生成SQL脚本,在数据库实例knowledge中生成表;demo中需要用到Article和Version两张表,这两张表分别表示文章的和文章的每个版本,并且假定每个版本的内容、作者、附件都可以改变,但是文章标题不可以修改。



图二 知识库系统的概念模型
(2)在建立的表中插入一些记录,其中包含一条:
insert into version(id, content) values(1,'上午好');
insert into version(id, content) values(2,'<title>上午好</title>');
insert into version (id, content) values(3,'我是中国人,我深深的爱着我的祖国和人民,我是人民的儿子');
步骤4 建立索引
以ctxtest用户连接到knowledge数据库
(1)创建首选项
begin tx_ddl.create_preference('my_lexer','chinese_vgram_lexer'); end;
(2)创建索引
create index myindex on version(content) indextype is ctxsys.context
parameters('lexer my_lexer');
如上命令以Oracle提供的中文分词器chinese_vgram_lexer对version表的content字段建立了索引。建立的索引保存在CTXSYS用户默认的临时表空间里以dr$打头的4个表: dr$myindex$i、dr$myindex$k、dr$myindex$r、dr$myindex$n,其中以表dr$myindex$i最为重要。查询一下该表
select token_text, token_count from dr$myindex$i;
可以发现该表中存储的就是对article表的content字段分析得到的全部索引项。
步骤5 执行查询
Select * from version where contains(content,’中国人’) >0;
可以查出刚刚插入表格中的第三条记录
步骤6 建立维护索引的JOB
索引在刚才执行创建索引的语句后被创建,但是此后对数据库执行的任何增删改操作都不会引起索引的同步更新。因此需要建立一个同步更新操作的JOB执行同步更新操作;
另一方面,在执行多次同步更新之后,索引区会引起索引项的稀释,势必需要优化,因此还需要为数据库建立一个定期优化索引结构的JOB.
这两个job可以建立如下:
同步sync:
VARIABLE jobno number;
BEGIN DBMS_JOB.SUBMIT(:jobno,'ctx_ddl.sync_index(''myindex'');', SYSDATE, 'SYSDATE + (1/24/4)');
commit; END;
优化optimizer:
VARIABLE jobno number;
BEGIN DBMS_JOB.SUBMIT(:jobno,'ctx_ddl.optimize_index(''myindex'',''FULL'');', SYSDATE, 'SYSDATE + 1');
commit; END;
其中, 第一个job的SYSDATE + (1/24/4)是指每隔15分钟同步一次,第二个job的SYSDATE + 1是每隔1天做一次全优化。具体的时间间隔,可以应用需要而定。

至此,全文检索功能已设置完成。

1.3 两个问题
1.3.1 Oracle Text 对HTML建立索引的支持
知识库系统一般采用在线编辑器编辑文章,所见即所得的文本一般采用html语法。而html源文件中大量的标记符号不应该参与与查询字符串的匹配,因为不仅这些如<title>这样的格式标记在搜索如“title”时不应该被搜索到、而且如果不加过滤的对这些部分建立索引项势,对于一个大型的文本查询系统而言会极大的影响效率。
回顾Oracle Text的体系结构图,Oracle Text在将文本分词创建索引项时已经充分考虑到了支持html、xml等格式化的文档在建立索引时过滤掉无表意内容的格式脚本。
这可以通过在创建索引时设置Section Groups区分组来实现。SQL语句如下:
BEGIN
ctx_ddl.create_section_group ('my_section_group', 'BASIC_SECTION_GROUP');
ctx_ddl.add_field_section (
group_name=> 'my_section_group',
section_name=> 'Title',
tag => 'title',
visible=> FALSE
);
END;/

DROP INDEX my_html_idx;
CREATE INDEX my_html_idx ON version( context )
INDEXTYPE IS ctxsys.CONTEXT
PARAMETERS( 'section group my_section_group' )/
SELECT id from version WHERE contains (content, '上午好 within title') > 0;
1.3.2 中文分词程序设置的改进
在为建立引擎创建lexer首选项时,设置的分词器是Oracle提供的chinese_vgram_lexer。实际上Oracle还提供了一个chinese_lexer. 比较而言,这个分词器分词算法更智能、效率更高。在demo中就表中第三条记录的content字段建立索引项时,索引项由chinese_vgram_lxer的53个减少到31个。
在官方文档中提到chinese_lexer仅支持UTF-8字符集的数据库,demo过程中,发现在zhs16gbk中也能够使用。

(未完,待续)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: