??xml version="1.0" encoding="utf-8" standalone="yes"?>久久久久午夜电影,国内精品在线视频,在线综合欧美http://www.aygfsteel.com/machilansing/category/14202.htmlLansing--Coding 不是? zh-cnTue, 27 Feb 2007 15:57:51 GMTTue, 27 Feb 2007 15:57:51 GMT60Lucene In Action Ch6 W记http://www.aygfsteel.com/machilansing/archive/2007/01/05/91910.htmlLansingLansingFri, 05 Jan 2007 02:27:00 GMThttp://www.aygfsteel.com/machilansing/archive/2007/01/05/91910.htmlhttp://www.aygfsteel.com/machilansing/comments/91910.htmlhttp://www.aygfsteel.com/machilansing/archive/2007/01/05/91910.html#Feedback0http://www.aygfsteel.com/machilansing/comments/commentRss/91910.htmlhttp://www.aygfsteel.com/machilansing/services/trackbacks/91910.html阅读全文

Lansing 2007-01-05 10:27 发表评论
]]>
Lucene In Action Ch4 W记http://www.aygfsteel.com/machilansing/archive/2007/01/05/91906.htmlLansingLansingFri, 05 Jan 2007 02:14:00 GMThttp://www.aygfsteel.com/machilansing/archive/2007/01/05/91906.htmlhttp://www.aygfsteel.com/machilansing/comments/91906.htmlhttp://www.aygfsteel.com/machilansing/archive/2007/01/05/91906.html#Feedback0http://www.aygfsteel.com/machilansing/comments/commentRss/91906.htmlhttp://www.aygfsteel.com/machilansing/services/trackbacks/91906.html阅读全文

Lansing 2007-01-05 10:14 发表评论
]]>
Lucene In Action Ch3 W记http://www.aygfsteel.com/machilansing/archive/2007/01/05/91905.htmlLansingLansingFri, 05 Jan 2007 02:11:00 GMThttp://www.aygfsteel.com/machilansing/archive/2007/01/05/91905.htmlhttp://www.aygfsteel.com/machilansing/comments/91905.htmlhttp://www.aygfsteel.com/machilansing/archive/2007/01/05/91905.html#Feedback0http://www.aygfsteel.com/machilansing/comments/commentRss/91905.htmlhttp://www.aygfsteel.com/machilansing/services/trackbacks/91905.html阅读全文

Lansing 2007-01-05 10:11 发表评论
]]>
Lucene In Action Ch2 W记http://www.aygfsteel.com/machilansing/archive/2007/01/05/91904.htmlLansingLansingFri, 05 Jan 2007 02:10:00 GMThttp://www.aygfsteel.com/machilansing/archive/2007/01/05/91904.htmlhttp://www.aygfsteel.com/machilansing/comments/91904.htmlhttp://www.aygfsteel.com/machilansing/archive/2007/01/05/91904.html#Feedback0http://www.aygfsteel.com/machilansing/comments/commentRss/91904.htmlhttp://www.aygfsteel.com/machilansing/services/trackbacks/91904.html阅读全文

Lansing 2007-01-05 10:10 发表评论
]]>
ORACLE 全文索引功能实现http://www.aygfsteel.com/machilansing/archive/2006/08/17/ORACLE.htmlLansingLansingThu, 17 Aug 2006 01:33:00 GMThttp://www.aygfsteel.com/machilansing/archive/2006/08/17/ORACLE.htmlhttp://www.aygfsteel.com/machilansing/comments/64049.htmlhttp://www.aygfsteel.com/machilansing/archive/2006/08/17/ORACLE.html#Feedback0http://www.aygfsteel.com/machilansing/comments/commentRss/64049.htmlhttp://www.aygfsteel.com/machilansing/services/trackbacks/64049.htmlORACLE 全文索引功能实现学习(fn)W记

前言Q?数据库工E师众所周知的一个事实是Q当Ҏ(gu)据库里的文本字段q行like(g)索的时候,M数据索引都是不v作用的,q样也就Dpȝ?x)承担额外的开销和负载压力,对于庞大的数据记录,对其中的文本字段q行关键字匹配,p定会(x)存在非常严重的效率障和性能障碍。因此,Z文本的全文烦(ch)引技术也逐渐兴v?
全文索引的技术原理ƈ不复杂,Ҏ(gu)落性的文本内容q行逐词分解Qƈ针对词出现频率,出现位置q行标记Q按照词本n的编码顺序存储ؓ(f)索引文g。这P在针对关键词q行(g)索的时候,׃?x)遍历所有的文本数据记录Q而是Ҏ(gu)索引文gq行有序查找Q这里面一个显见的事实是,通过有序索引查找关键词,对于量的数据记录而言Q也只需要很次数的指针跌{Q(数量为X的烦(ch)引记录,查询特定记录的指针蟩转次数最多ؓ(f)Log2(x)。)(j)卛_完成搜烦(ch)Q而无d整遍历整个数据表或文仉?
但是全文索引技术的实现却ƈ不简单,针对中文的尤其如此,英文文本中,I格是天然的分词标记Q而中文段落却无法通过q样单的途径分词Q因此基于常用语词典和一些语a识别规则的分词技术成ZU非帔R的技术门槛,q好Q很多商业公司提供了(jin)非常成熟的商业品,使我{可以坐享其成,快速搭建全文搜索的q_?

ORACLE INTERMEDIA介绍
ORACLE Intermedia是ORACLE公司官方发布的用来管理多媒体数据的数据库理模块Q通过它可以进行有效的视频Q音频,囄{文件的l一存储Q调用和相关处理Q同时其中也包括一个Oracle Intermdedia Text功能模块Q能够对多种格式文档q行分词索引处理Q也提供?jin)用自然语法或高查询?gu)q行跨文本查询的途径Q可以查询word, PDF,RTF{格式的文g和数据?
Oracle Intermedia 的烦(ch)引效率和查询效率Q据一些公开数据上看要远高于Microsoft的Index ServerQ而且本nhq_无关Ҏ(gu),另外作ؓ(f)数据库品,可以很好的和数据库应用进行整合,q一点也是纯_的文g索引pȝ所无法实现的。当?dng)作?f)通用的数据库产品QOracle不可能针对全文烦(ch)引做到最大限度的优化Q因此对于高q发大容量的搜烦(ch)引擎应用QOracle的方案可能就无法满Q这一点也是必L前声明的?

全文索引实现步骤
步骤1Q查看Oracle Intermedia是否正确安装。Oracle Intermdeia是Oracle的一个附带模块,安装q程中选择卛_?
步骤2Q设|词法解析器
oracleҎ(gu)不同语言Q有不同的词法解析器Q以下说明我们可能用到的三个
basic_lexerQ针对英语环境,以空gؓ(f)分词标记Q同时能分L一些“噪音”单词,?“if? “is”等?
chinese_vgram_lexerQ专用的汉语分析器,按字为单元分析中文,法单,可以一|打中文用词,但是效率差强人意?
chinese_lexerQ可以识别大部分常用短语和词汇,不会(x)产生大量冗余数据Q有很好的实用性,但是语言支持只能为UTF-8~码Q不支持zhs16gbk字符集?
以ctxsys用户登陆pȝQ执行:(x)
begin ctx_ddl.create_preference('my_lexer','chinese_vgram_lexer'); end;
q里假设我们的语法解析器命名为my_lexerQ这个名UC可以Ҏ(gu)实际应用变化?
步骤3Q徏立烦(ch)引字D?
我的试用例保存在systemI间Q表名ؓ(f)my_docsQ字D名为docQ字D늱型ؓ(f)blobQ存储标准word doc文g?
仍旧保持ctxsys帐户登陆Q执行如下操?
create index system.myindex on system.my_docs(doc) indextype is ctxsys.context parameters(‘lexer?’my_lexer? ;
步骤4Q同步操作(syncQ及(qing)优化操作
以system 登陆Q同步操作执?
exec ctx_ddl.sync_index('myindex');

创徏同步定时d代码如下
VARIABLE jobno number;
BEGIN
  DBMS_JOB.SUBMIT(:jobno,'ctx_ddl.sync_index(''myindex'');',
  SYSDATE, 'SYSDATE + (1/24/4)');
  commit;
  END;
/
以system登陆Q优化烦(ch)引操作执?
exec ctx_ddl.optimize_index('myindex','FULL');
创徏优化定时d代码如下
VARIABLE jobno number;
  BEGIN
  DBMS_JOB.SUBMIT(:jobno,'ctx_ddl.optimize_index(''myindex'',''FULL'');',
  SYSDATE, 'SYSDATE + 1');
  commit;
  END;
/
步骤5Q测?
select id from my_docs where contains(doc,'关键?)>0
ȝQ?
该学?fn)笔记内容大部分可以通过搜烦(ch)引擎扑ֈQƈ非本人原创内容,本文全部l个人在windowsq_下,在oracle 9i下测试完成,留档记录Qؓ(f)日后的项目和产品开发做技术准备?

Lansing 2006-08-17 09:33 发表评论
]]>
全文索引—CONTAINS语法http://www.aygfsteel.com/machilansing/archive/2006/08/17/CONTAINS.htmlLansingLansingThu, 17 Aug 2006 01:31:00 GMThttp://www.aygfsteel.com/machilansing/archive/2006/08/17/CONTAINS.htmlhttp://www.aygfsteel.com/machilansing/comments/64048.htmlhttp://www.aygfsteel.com/machilansing/archive/2006/08/17/CONTAINS.html#Feedback0http://www.aygfsteel.com/machilansing/comments/commentRss/64048.htmlhttp://www.aygfsteel.com/machilansing/services/trackbacks/64048.html全文索引—CONTAINS语法

全文索引—CONTAINS语法
全文索引——CONTAINS 语法
我们通常?WHERE 子句中?CONTAINS Q就象这P(x)SELECT * FROM table_name WHERE CONTAINS(fullText_column,'search contents')?

我们通过例子来学?fn),假设有?studentsQ其中的 address 是全文本(g)索的列?br />1. 查询住址在北京的学生
SELECT student_id,student_name
FROM students
WHERE CONTAINS( address, 'beijing' )
remark: beijing是一个单词,要用单引hh?br />
2. 查询住址在河北省的学?br />SELECT student_id,student_name
FROM students
WHERE CONTAINS( address, '"HEIBEI province"' )
remark: HEBEI province是一个词l,在单引号里还要用双引hh?br />
3. 查询住址在河北省或北京的学生
SELECT student_id,student_name
FROM students
WHERE CONTAINS( address, '"HEIBEI province" OR beijing' )
remark: 可以指定逻辑操作W?包括 AND QAND NOTQOR )?br />
4. 查询?'南京? 字样的地址
SELECT student_id,student_name
FROM students
WHERE CONTAINS( address, 'nanjing NEAR road' )
remark: 上面的查询将q回包含 'nanjing road'Q?nanjing east road'Q?nanjing west road' {字L(fng)地址?br />          A NEAR BQ就表示条gQ?A 靠近 B?br />
5. 查询?'? 开头的地址
SELECT student_id,student_name
FROM students
WHERE CONTAINS( address, '"hu*"' )
remark: 上面的查询将q回包含 'hubei'Q?hunan' {字L(fng)地址?br />          C?*Q不?%?br />
6. cM加权的查?br />SELECT student_id,student_name
FROM students
WHERE CONTAINS( address, 'ISABOUT (city weight (.8), county wright (.4))' )
remark: ISABOUT 是这U查询的关键字,weight 指定?jin)一个介?0~1之间的数Q类似系?我的理解)。表CZ同条件有不同的侧重?br />
7. 单词的多态查?br />SELECT student_id,student_name
FROM students
WHERE CONTAINS( address, 'FORMSOF (INFLECTIONAL,street)' )
remark: 查询返回包?'street'Q?streets'{字L(fng)地址?br />         对于动词返回它的不同的时态,如:(x)dryQ将q回 dryQdriedQdrying {等?img src ="http://www.aygfsteel.com/machilansing/aggbug/64048.html" width = "1" height = "1" />

Lansing 2006-08-17 09:31 发表评论
]]>
ZJava的全文烦(ch)?(g)索引擎——Lucenehttp://www.aygfsteel.com/machilansing/archive/2006/08/17/Lucene.htmlLansingLansingThu, 17 Aug 2006 01:08:00 GMThttp://www.aygfsteel.com/machilansing/archive/2006/08/17/Lucene.htmlhttp://www.aygfsteel.com/machilansing/comments/64037.htmlhttp://www.aygfsteel.com/machilansing/archive/2006/08/17/Lucene.html#Feedback0http://www.aygfsteel.com/machilansing/comments/commentRss/64037.htmlhttp://www.aygfsteel.com/machilansing/services/trackbacks/64037.html ZJava的全文烦(ch)?(g)索引擎——Lucene

Lucene不是一个完整的全文索引应用Q而是是一个用Java写的全文索引引擎工具包,它可以方便的嵌入到各U应用中实现针对应用的全文烦(ch)?(g)索功能?/p>

Lucene的作者:(x)Lucene的A(ch)献?a >Doug Cutting是一位资深全文烦(ch)?(g)索专Ӟ曄是V-Twin搜烦(ch)引擎(Apple的Copland操作pȝ的成׃一)的主要开发者,后在Excite担Q高pȝ架构设计师,目前从事于一些INTERNET底层架构的研I。他贡献出的Lucene的目标是为各U中型应用E序加入全文(g)索功能?/p>

Lucene的发展历E:(x)早先发布在作者自qwww.lucene.comQ后来发布在SourceForgeQ?001q年底成为APACHE基金?x)jakarta的一个子目Q?a >http://jakarta.apache.org/lucene/

已经有很多Java目都用了(jin)Lucene作ؓ(f)其后台的全文索引引擎Q比较著名的有:(x)

  • J iveQWEB论坛pȝQ?
  • EyebrowsQ邮件列表HTML归档/览/查询pȝQ本文的主要参考文档?a >TheLucene search engine: Powerful, flexible, and free”作者就是EyeBrowspȝ的主要开发者之一Q而EyeBrows已经成ؓ(f)目前APACHE目的主要邮件列表归档系l?
  • Cocoon:ZXML的web发布框架Q全文检索部分用了(jin)Lucene
  • Eclipse:ZJava的开攑ּ发^収ͼ帮助部分的全文烦(ch)引用了(jin)Lucene

对于中文用户来说Q最兛_(j)的问题是其是否支持中文的全文(g)索。但通过后面对于Lucene的结构的介绍Q你?x)?jin)解到׃Lucene良好架构设计Q对中文的支持只需对其语言词法分析接口q行扩展p实现对中文检索的支持?/p>

全文(g)索的实现机制

Lucene的API接口设计的比较通用Q输入输出结构都很像数据库的?=>记录==>字段Q所以很多传l的应用的文件、数据库{都可以比较方便的映到Lucene的存储结?接口中。M上看Q可以先?b>Lucene当成一个支持全文烦(ch)引的数据库系l?/b>?/p>

比较一下Lucene和数据库Q?/p>
Lucene 数据?/td>
索引数据源:(x)doc(field1,field2...) doc(field1,field2...)
\ indexer /
_____________
| Lucene Index|
--------------
/ searcher \
l果输出QHits(doc(field1,field2) doc(field1...))
 索引数据源:(x)record(field1,field2...) record(field1..)
\ SQL: insert/
_____________
| DB Index |
-------------
/ SQL: select \
l果输出Qresults(record(field1,field2..) record(field1...))
DocumentQ一个需要进行烦(ch)引的“单元?br />一个Document由多个字D늻?/td> RecordQ记录,包含多个字段
FieldQ字D?/td> FieldQ字D?/td>
HitsQ查询结果集Q由匚w的Documentl成 RecordSetQ查询结果集Q由多个Recordl成

全文(g)??like "%keyword%"

通常比较厚的书籍后面常常附关键词索引表(比如Q北京:(x)12, 34,上vQ?,77……)(j)Q它能够帮助读者比较快地找到相兛_容的늠。而数据库索引能够大大提高查询的速度原理也是一P惛_一下通过书后面的索引查找的速度要比一一地d定w多少倍……而烦(ch)引之所以效率高Q另外一个原因是它是排好序的?b>对于(g)索系l来说核?j)是一个排序问?/b>?/p>

׃数据库烦(ch)引不是ؓ(f)全文索引设计的,因此Q?b>使用like "%keyword%"Ӟ数据库烦(ch)引是不v作用?/b>Q在使用like查询Ӟ搜烦(ch)q程又变成类g一页M的遍历过E了(jin)Q所以对于含有模p查询的数据库服务来_(d)LIKEҎ(gu)能的危x极大的。如果是需要对多个关键词进行模p匹配:(x)like"%keyword1%" and like "%keyword2%" ...其效率也可惌知?jin)?/p>

所以徏立一个高效检索系l的关键是徏立一个类gU技索引一L(fng)反向索引机制Q将数据源(比如多篇文章Q排序顺序存储的同时Q有另外一个排好序的关键词列表Q用于存储关键词==>文章映射关系Q利用这L(fng)映射关系索引Q[关键?=>出现关键词的文章~号Q出现次敎ͼ甚至包括位置Qv始偏U量Q结束偏U量Q,出现频率]Q检索过E就是把模糊查询变成多个可以利用索引的精查询的逻辑l合的过E?/b>。从而大大提高了(jin)多关键词查询的效率,所以,全文(g)索问题归l到最后是一个排序问题?/p>

由此可以看出模糊查询相对数据库的_查询是一个非怸定的问题,q也是大部分数据库对全文(g)索支持有限的原因。Lucene最核心(j)的特征是通过Ҏ(gu)的烦(ch)引结构实C(jin)传统数据库不擅长的全文烦(ch)引机Ӟq提供了(jin)扩展接口Q以方便针对不同应用的定制?/p>

可以通过一下表格对比一下数据库的模p查询:(x)

  Lucene全文索引引擎 数据?/td>
索引 数据源中的数据都通过全文索引一一建立反向索引 对于LIKE查询来说Q数据传l的索引是根本用不上的。数据需要逐个便利记录q行GREP式的模糊匚wQ比有烦(ch)引的搜烦(ch)速度要有多个数量U的下降?/td>
匚w效果 通过词元(term)q行匚wQ通过语言分析接口的实玎ͼ可以实现对中文等非英语的支持?/td> 使用Qlike "%net%" ?x)把netherlands也匹配出来,
多个关键词的模糊匚wQ用like "%com%net%"Q就不能匚w词序颠倒的xxx.net..xxx.com
匚w?/td> 有匹配度法Q将匚wE度Q相似度Q比较高的结果排在前面?/td> 没有匚wE度的控Ӟ(x)比如有记录中net出现5词和出现1ơ的Q结果是一L(fng)?/td>
l果输出 通过特别的算法,最匚w度最高的?00条结果输出,l果集是~冲式的批量读取的?/td> q回所有的l果集,在匹配条目非常多的时候(比如上万条)(j)需要大量的内存存放q些临时l果集?/td>
可定制?/td> 通过不同的语a分析接口实现Q可以方便的定制出符合应用需要的索引规则Q包括对中文的支持)(j) 没有接口或接口复杂,无法定制
l论 高负载的模糊查询应用Q需要负责的模糊查询的规则,索引的资料量比较?/td> 使用率低Q模p匹配规则简单或者需要模p查询的资料量少

全文(g)索和数据库应用最大的不同在于Q让
最相关?/span> ?00条结果满?8%以上用户的需?br />
Lucene的创C处:(x)

大部分的搜烦(ch)Q数据库Q引擎都是用B?wi)结构来l护索引Q烦(ch)引的更新?x)导致大量的IO操作QLucene在实CQ对此稍微有所改进Q不是维护一个烦(ch)引文Ӟ而是在扩展烦(ch)引的时候不断创建新的烦(ch)引文Ӟ然后定期的把q些新的烦(ch)引文件合q到原先的大索引中(针对不同的更新策略,Ҏ(gu)的大可以调_(d)(j)Q这样在不媄(jing)响检索的效率的前提下Q提高了(jin)索引的效率?/p>

Lucene和其他一些全文检索系l?应用的比较:(x)

  Lucene 其他开源全文检索系l?/td>
增量索引和批量烦(ch)?/td> 可以q行增量的烦(ch)?Append)Q可以对于大量数据进行批量烦(ch)引,q且接口设计用于优化扚w索引和小扚w的增量烦(ch)引?/td> 很多pȝ只支持批量的索引Q有时数据源有一点增加也需要重建烦(ch)引?/td>
数据?/td> Lucene没有定义具体的数据源Q而是一个文档的l构Q因此可以非常灵zȝ适应各种应用Q只要前端有合适的转换器把数据源{换成相应l构Q, 很多pȝ只针对网,~Z其他格式文档的灵zL?/td>
索引内容抓取 Lucene的文档是由多个字D늻成的Q甚臛_以控刉些字D需要进行烦(ch)引,那些字段不需要烦(ch)引,q一步烦(ch)引的字段也分为需要分词和不需要分词的cdQ?br />   需要进行分词的索引Q比如:(x)标题Q文章内容字D?br />   不需要进行分词的索引Q比如:(x)作?日期字段 ~Z通用性,往往文档整个烦(ch)引了(jin)
语言分析 通过语言分析器的不同扩展实现Q?br />可以qo(h)掉不需要的词:(x)an the of {,
西文语法分析Q将jumps jumped jumper都归l成jumpq行索引/(g)?br />非英文支持:(x)对亚z语aQ阿拉伯语言的烦(ch)引支?/td>
~Z通用接口实现
查询分析 通过查询分析接口的实玎ͼ可以定制自己的查询语法规则:(x)
比如Q?多个关键词之间的 + - and or关系{?/td>
 
q发讉K 能够支持多用L(fng)使用  

 

关于亚洲语言的的切分词问?Word Segment)

对于中文来说Q全文烦(ch)引首先还要解决一个语a分析的问题,对于英文来说Q语句中单词之间是天焉过I格分开的,但亚z语a的中日韩文语句中的字是一个字挨一个,所有,首先要把语句中按“词”进行烦(ch)引的话,q个词如何切分出来就是一个很大的问题?/p>

首先Q肯定不能用单个字符?si-gram)为烦(ch)引单元,否则查“上”时Q不能让含有“v上”也匚w?/p>

但一句话Q“北京天安门”,计算机如何按照中文的语言?fn)惯q行切分呢?
“北?天安门?q是“北 ?天安门”?让计机能够按照语言?fn)惯q行切分Q往往需要机器有一个比较丰富的词库才能够比较准的识别?gu)句中的单词?/p>

另外一个解决的办法是采用自动切分算法:(x)单词按?元语?bigram)方式切分出来Q比如:(x)
"北京天安? ==> "北京 京天 天安 安门"?/p>

q样Q在查询的时候,无论是查?北京" q是查询"天安?Q将查询词组按同L(fng)规则q行切分Q?北京"Q?天安安门"Q多个关键词之间按与"and"的关pȝ合,同样能够正确地映到相应的烦(ch)引中。这U方式对于其他亚z语aQ韩文,日文都是通用的?/p>

Z自动切分的最大优Ҏ(gu)没有词表l护成本Q实现简单,~点是烦(ch)引效率低Q但对于中小型应用来_(d)Z2元语法的切分q是够用的。基?元切分后的烦(ch)引一般大和源文件差不多Q而对于英文,索引文g一般只有原文g?0%-40%不同Q?/p>

自动切分 词表切分
实现 实现非常?/td> 实现复杂
查询 增加?jin)查询分析的复杂E度Q?/td> 适于实现比较复杂的查询语法规?/td>
存储效率 索引冗余大,索引几乎和原文一样大 索引效率高,为原文大的30Q左?/td>
l护成本 无词表维护成?/td> 词表l护成本非常高:(x)中日韩等语言需要分别维护?br />q需要包括词频统计等内容
适用领域 嵌入式系l:(x)q行环境资源有限
分布式系l:(x)无词表同步问?br />多语a环境Q无词表l护成本
Ҏ(gu)询和存储效率要求高的专业搜烦(ch)引擎

目前比较大的搜烦(ch)引擎的语a分析法一般是Z以上2个机制的l合。关于中文的语言分析法Q大家可以在Google查关键词"wordsegment search"能找到更多相关的资料?/p>

安装和?/b>

下蝲Q?a >http://jakarta.apache.org/lucene/

注意QLucene中的一些比较复杂的词法分析是用JavaCC生成的(JavaCCQJavaCompilerCompilerQ纯Java的词法分析生成器Q,所以如果从源代码编译或需要修改其中的QueryParser、定制自q词法分析器,q需要从https://javacc.dev.java.net/下蝲javacc?/p>

lucene的组成结构:(x)对于外部应用来说索引模块(index)和检索模?search)是主要的外部应用入口

org.apache.Lucene.search/ 搜烦(ch)入口
org.apache.Lucene.index/ 索引入口
org.apache.Lucene.analysis/ 语言分析?/td>
org.apache.Lucene.queryParser/ 查询分析?/td>
org.apache.Lucene.document/ 存储l构
org.apache.Lucene.store/  底层IO/存储l构
org.apache.Lucene.util/ 一些公用的数据l构

单的例子演示一下Lucene的用方法:(x)

索引q程Q从命o(h)行读取文件名Q多个)(j)Q将文g分\?path字段)和内?body字段)2个字D进行存储,q对内容q行全文索引Q烦(ch)引的单位是Document对象Q每个Document对象包含多个字段Field对象Q针对不同的字段属性和数据输出的需求,对字D还可以选择不同的烦(ch)?存储字段规则Q列表如下:(x)
Ҏ(gu)切词索引存储用?/th>
Field.Text(String name, String value)YesYesYes切分词烦(ch)引ƈ存储Q比如:(x)标题Q内容字D?/td>
Field.Text(String name, Reader value)YesYesNo切分词烦(ch)引不存储Q比如:(x)META信息Q?br />不用于返回显C,但需要进行检索内?/td>
Field.Keyword(String name, String value)NoYesYes不切分烦(ch)引ƈ存储Q比如:(x)日期字段
Field.UnIndexed(String name, String value)NoNoYes不烦(ch)引,只存储,比如Q文件\?/td>
Field.UnStored(String name, String value)YesYesNo只全文烦(ch)引,不存?/td>
public class IndexFiles { 
//使用Ҏ(gu)Q? IndexFiles [索引输出目录] [索引的文件列表] ...
public static void main(String[] args) throws Exception {
String indexPath = args[0];
IndexWriter writer;
//用指定的语言分析器构造一个新的写索引器(W?个参数表C是否ؓ(f)q加索引Q?br /> writer = new IndexWriter(indexPath, new SimpleAnalyzer(), false);

for (int i=1; i<args.length; i++) {
System.out.println("Indexing file " + args[i]);
InputStream is = new FileInputStream(args[i]);

//构造包?个字DField的Document对象
//一个是路径path字段Q不索引Q只存储
//一个是内容body字段Q进行全文烦(ch)引,q存?br /> Document doc = new Document();
doc.add(Field.UnIndexed("path", args[i]));
doc.add(Field.Text("body", (Reader) new InputStreamReader(is)));
//文档写入烦(ch)?br /> writer.addDocument(doc);
is.close();
};
//关闭写烦(ch)引器
writer.close();
}
}
 

索引q程中可以看刎ͼ(x)

  • 语言分析器提供了(jin)抽象的接口,因此语言分析(Analyser)是可以定制的Q虽然lucene~省提供?个比较通用的分析器SimpleAnalyser和StandardAnalyserQ这2个分析器~省都不支持中文Q所以要加入对中文语a的切分规则,需要修改这2个分析器?
  • Luceneq没有规定数据源的格式,而只提供?jin)一个通用的结构(Document对象Q来接受索引的输入,因此输入的数据源可以是:(x)数据库,W(xu)ORD文档QPDF文档QHTML文档……只要能够设计相应的解析转换器将数据源构造成成Docuement对象卛_q行索引?
  • 对于大批量的数据索引Q还可以通过调整IndexerWrite的文件合q率属性(mergeFactorQ来提高扚w索引的效率?

(g)索过E和l果昄Q?/p>

搜烦(ch)l果q回的是Hits对象Q可以通过它再讉KDocument==>Field中的内容?/p>

假设Ҏ(gu)body字段q行全文(g)索,可以查询结果的path字段和相应查询的匚w?score)打印出来Q?/p>

public class Search { 
public static void main(String[] args) throws Exception {
String indexPath = args[0], queryString = args[1];
//指向索引目录的搜索器
Searcher searcher = new IndexSearcher(indexPath);
//查询解析器:(x)使用和烦(ch)引同L(fng)语言分析?br /> Query query = QueryParser.parse(queryString, "body",
new SimpleAnalyzer());
//搜烦(ch)l果使用Hits存储
Hits hits = searcher.search(query);
//通过hits可以讉K到相应字D늚数据和查询的匚w?br /> for (int i=0; i<hits.length(); i++) {
System.out.println(hits.doc(i).get("path") + "; Score: " +
hits.score(i));
};
}
}
在整个检索过E中Q语a分析器,查询分析器,甚至搜烦(ch)器(SearcherQ都是提供了(jin)抽象的接口,可以Ҏ(gu)需要进行定制?

Hacking Lucene

化的查询分析?/b>

个h感觉lucene成ؓ(f)JAKARTA目后,d?jin)太多的旉用于调试日趋复杂QueryParserQ而其中大部分是大多数用户q不很熟(zhn)的Q目前LUCENE支持的语法:(x)

Query ::= ( Clause )*
Clause ::= ["+", "-"] [<TERM> ":"] ( <TERM> | "(" Query ")")

中间的逻辑包括Qand or + - &&||{符P而且q有"短语查询"和针对西文的前缀/模糊查询{,个h感觉对于一般应用来_(d)q些功能有一些华而不实,其实能够实现目前cM于Google的查询语句分析功能其实对于大多数用户来说已经够了(jin)。所以,Lucene早期版本的QueryParser仍是比较好的选择?/p>

d修改删除指定记录QDocumentQ?/b>

Lucene提供?jin)?ch)引的扩展机制Q因此烦(ch)引的动态扩展应该是没有问题的,而指定记录的修改也似乎只能通过记录的删除,然后重新加入实现。如何删除指定的记录呢?删除的方法也很简单,只是需要在索引时根据数据源中的记录ID专门另徏索引Q然后利用IndexReader.delete(Termterm)Ҏ(gu)通过q个记录ID删除相应的Document?/p>

Ҏ(gu)某个字段值的排序功能

lucene~省是按照自q相关度算法(scoreQ进行结果排序的Q但能够Ҏ(gu)其他字段q行l果排序是一个在LUCENE的开发邮件列表中l常提到的问题,很多原先Z数据库应用都需要除?jin)基于匹配度QscoreQ以外的排序功能。而从全文(g)索的原理我们可以?jin)解刎ͼM不基于烦(ch)引的搜烦(ch)q程效率都会(x)D效率非常的低Q如果基于其他字D늚排序需要在搜烦(ch)q程中访问存储字D,速度回大大降低,因此非常是不可取的?/p>

但这里也有一个折中的解决Ҏ(gu)Q在搜烦(ch)q程中能够媄(jing)响排序结果的只有索引中已l存储的docID和scoreq?个参敎ͼ所以,Zscore以外的排序,其实可以通过数据源预先排好序,然后Ҏ(gu)docIDq行排序来实现。这样就避免?jin)在LUCENE搜烦(ch)l果外对l果再次q行排序和在搜烦(ch)q程中访问不在烦(ch)引中的某个字D倹{?/p>

q里需要修改的是IndexSearcher中的HitCollectorq程Q?/p>

...
 scorer.score(new HitCollector() {
private float minScore = 0.0f;
public final void collect(int doc, float score) {
if (score > 0.0f && // ignore zeroed buckets
(bits==null || bits.get(doc))) { // skip docs not in bits
totalHits[0]++;
if (score >= minScore) {
/* 原先QLucenedocID和相应的匚w度score例入l果命中列表中:(x)
* hq.put(new ScoreDoc(doc, score)); // update hit queue
* 如果用doc ?1/doc 代替 scoreQ就实现?jin)根据docID排或逆排
* 假设数据源烦(ch)引时已经按照某个字段排好?jin)序Q而结果根据docID排序也就实现?br /> * 针对某个字段的排序,甚至可以实现更复杂的score和docID的拟合?br /> */
hq.put(new ScoreDoc(doc, (float) 1/doc ));
if (hq.size() > nDocs) { // if hit queue overfull
hq.pop(); // remove lowest in hit queue
minScore = ((ScoreDoc)hq.top()).score; // reset minScore
}
}
}
}
}, reader.maxDoc());

更通用的输入输出接?/b>

虽然lucene没有定义一个确定的输入文档格式Q但来多的h惛_使用一个标准的中间格式作ؓ(f)Lucene的数据导入接口,然后其他数据Q比如PDF只需要通过解析器{换成标准的中间格式就可以q行数据索引?jin)。这个中间格式主要以XMLZQ类似实现已l不?Q?个:(x)

数据? WORD       PDF     HTML    DB       other
\ | | | /
XML中间格式
|
Lucene INDEX

目前q没有针对MSWord文档的解析器Q因为Word文档和基于ASCII的RTF文档不同Q需要用COM对象机制解析。这个是我在Google上查的相兌料:(x)http://www.intrinsyc.com/products/enterprise_applications.asp
另外一个办法就是把Word文档转换成textQ?a >http://www.winfield.demon.nl/index.html


索引q程优化

索引一般分2U情况,一U是批量的索引扩展Q一U是大批量的索引重徏。在索引q程中,q不是每ơ新的DOC加入q去索引都重新进行一ơ烦(ch)引文件的写入操作Q文件I/O是一仉常消耗资源的事情Q?/p>

Lucene先在内存中进行烦(ch)引操作,q根据一定的扚wq行文g的写入。这个批ơ的间隔大Q文件的写入ơ数少Q但占用内存?x)很多。反之占用内存少Q但文gIO操作频繁Q烦(ch)引速度?x)很慢。在IndexWriter中有一个MERGE_FACTOR参数可以帮助你在构造烦(ch)引器后根据应用环境的情况充分利用内存减少文g的操作。根据我的用经验:(x)~省Indexer是每20条记录烦(ch)引后写入一ơ,每将MERGE_FACTOR增加50倍,索引速度可以提高1倍左叟?br />

搜烦(ch)q程优化

lucene支持内存索引Q这L(fng)搜烦(ch)比基于文件的I/O有数量的速度提升?br />http://www.onjava.com/lpt/a/3273
而尽可能减少IndexSearcher的创建和Ҏ(gu)索结果的前台的缓存也是必要的?br />

Lucene面向全文(g)索的优化在于首次索引(g)索后Qƈ不把所有的记录QDocumentQ具体内容读取出来,而v只将所有结果中匚w度最高的?00条结果(TopDocsQ的ID攑ֈl果集缓存中q返回,q里可以比较一下数据库(g)索:(x)如果是一?0,000条的数据库检索结果集Q数据库是一定要把所有记录内定w取得以后再开始返回给应用l果集的。所以即使检索匹配L很多QLucene的结果集占用的内存空间也不会(x)很多。对于一般的模糊(g)索应用是用不到这么多的结果的Q头100条已l可以满?0%以上的检索需求?br />

如果首批~存l果数用完后q要d更后面的l果时Searcher?x)再ơ检索ƈ生成一个上ơ的搜烦(ch)~存数大1倍的~存Qƈ再重新向后抓取。所以如果构造一个SearcherL1Q?20条结果,Searcher其实是进行了(jin)2ơ搜索过E:(x)?00条取完后Q缓存结果用完,Searcher重新(g)索再构造一?00条的l果~存Q依此类推,400条缓存,800条缓存。由于每ơSearcher对象消失后,q些~存也访问那不到?jin),你有可能惛_l果记录~存下来Q缓存数量保证?00以下以充分利用首ơ的l果~存Q不让Lucene费多次(g)索,而且可以分q行l果~存?br />

Lucene的另外一个特Ҏ(gu)在收集结果的q程中将匚w度低的结果自动过滤掉?jin)。这也是和数据库应用需要将搜烦(ch)的结果全部返回不同之处?/p>

我的一些尝?/a>Q?/p>

从Lucene学到更多

Luene的确是一个面对对象设计的典范

  • 所有的问题都通过一个额外抽象层来方便以后的扩展和重用:(x)你可以通过重新实现来达到自q目的Q而对其他模块而不需要;
  • 单的应用入口Searcher, IndexerQƈ调用底层一pdlg协同的完成搜索Q务;
  • 所有的对象的Q务都非常专一Q比如搜索过E:(x)QueryParser分析查询语句{换成一pd的精查询的l合(Query),通过底层的烦(ch)引读取结构IndexReaderq行索引的读取,q用相应的打分器l搜索结果进行打?排序{。所有的功能模块原子化程度非帔RQ因此可以通过重新实现而不需要修改其他模块。?
  • 除了(jin)灉|的应用接口设计,Luceneq提供了(jin)一些适合大多数应用的语言分析器实玎ͼSimpleAnalyser,StandardAnalyserQ,q也是新用户能够很快上手的重要原因之一?

q些优点都是非常值得在以后的开发中学习(fn)借鉴的。作Z个通用工具包,Lunece的确l予?jin)需要将全文(g)索功能嵌入到应用中的开发者很多的便利?/p>

此外Q通过对Lucene的学?fn)和使用Q我也更深刻地理解了(jin)Z么很多数据库优化设计中要求,比如Q?/p>

  • 可能对字段q行索引来提高查询速度Q但q多的烦(ch)引会(x)Ҏ(gu)据库表的更新操作变慢Q而对l果q多的排序条Ӟ实际上往往也是性能的杀手之一?
  • 很多商业数据库对大批量的数据插入操作?x)提供一些优化参敎ͼq个作用和烦(ch)引器的merge_factor的作用是cM的,
  • 20%/80%原则Q查的结果多q不{于质量好,其对于q回l果集很大,如何优化q头几十条结果的质量往往才是最重要的?
  • 可能让应用从数据库中获得比较小的结果集Q因为即使对于大型数据库Q对l果集的随机讉K也是一个非常消耗资源的操作?br />

参考资料:(x)

Apache: Lucene Project
http://jakarta.apache.org/lucene/
Lucene开?用户邮g列表归档
Lucene-dev@jakarta.apache.org
Lucene-user@jakarta.apache.org

The Lucene search engine: Powerful, flexible, and free
http://www.javaworld.com/javaworld/jw-09-2000/jw-0915-Lucene_p.html

Lucene Tutorial
http://www.darksleep.com/puff/lucene/lucene.html

Notes on distributed searching with Lucene
http://home.clara.net/markharwood/lucene/

中文语言的切分词
http://www.google.com/search?sourceid=navclient&hl=zh-CN&q=chinese+word+segment

搜烦(ch)引擎工具介绍
http://searchtools.com/

Lucene作者Cutting的几论文和专利
http://lucene.sourceforge.net/publications.html 

Lucene?NET实现QdotLucene
http://sourceforge.net/projects/dotlucene/

Lucene作者Cutting的另外一个项目:(x)ZJava的搜索引擎Nutch
http://www.nutch.org/   http://sourceforge.net/projects/nutch/

关于Z词表和N-Gram的切分词比较
http://china.nikkeibp.co.jp/cgi-bin/china/news/int/int200302100112.html

2005-01-08 Cutting在Pisa大学做的关于Lucene的讲座:(x)非常详细的Lucene架构解说



Lansing 2006-08-17 09:08 发表评论
]]>
վ֩ģ壺 ʲ| ½| | ֶ| | | ϲ| | | | ζ| | | | | | | ¡| | | | | | ½| | Ϫ| ľ| ˳| | | Ͷ| Ѯ| Ϫ| | ޻| | | | | | |