??xml version="1.0" encoding="utf-8" standalone="yes"?>
不过谈到q个排名和打分问题,咱哥们儿q是应该在一?/span>
合计合计q个事儿
Q?/span>
1. Z么要搞公共排名,而不是个人排名?
个h排名Q读?a onclick="return top.js.OpenExtLink(window,event,this)" target="_blank">老白的文?/a>之后Q才理解q是一个个人知识管理的问题。其实绝大多Chq不订阅 谈到打分Q更是这P没有排名和比较,分数没有意?wbr>。老白其实也可以根据自己心中的分数搞出来一个老白阅读?wbr>Q和胡润财富榜一h为大安d客的重要参照依据?/p>
我没有老白?/span>
Keso
q样大的影响力,也没有许多时间来一一甄别和评判众多博?wbr>Q只好和大家一P要么期盼老白或?/span>
Keso
能够搞出来一个,要么p跟潮,看看有没有社会化评h(hun)的体pd?wbr>法?/span>
2. Z么没有用页面访问量Q?/strong>
q个东西太容易造假Q而且不能反映博客的水q_质量 没有使用订阅者倒不是因为担心造假Q这个问题比较复杂?/p>
仅有订阅数是不以表明博客的价倹{比如,有两?/span>
Blogger
Q?/span>
A
?/span>
B
?/span>
A
?/span>
10
个订阅者,
B
?/span>
15
个订阅者,能简单的?/span>
B
比
A
更有价值吗Q如果说
A
的订阅者都是象老白Q?/span>
Keso
q样的大牛,?/span>
B
的订阅者都是自己刚开始写博客的小兄弟们,
A
?/span>
B
的h(hun)值那个高Q这很难说了?/span>
所?/span>
Blogger
有没有h(hun)D要看订阅者的权倹{这L(fng)话,问题来了。凭什么说
q个思\不仅仅能用在|页链接的排名上Q同栯可以用在订阅关系?wbr>博客之间的相互链接上。不q最q有人告诉我Q以色列数学家找Z
Page Rank
的缺P认ؓ
PR
法没有考虑面的更新程度,一旦一个页面被一?/span>
PR
值高的页面链接了Q那׃x怺Q不用更C能保持很高的
PR
倹{有兴趣的h可以参看一?q里。我们在此略q不表?/span>
如果使用了类?/span>
PR
法的订阅数Q这个可行吗Q基本上q是不可行的Q因?/span>
Blogger
是无法知道自q博客被多h订阅和观看的Q不同的客户?wbr>Q还有许多象
Bloglines
Q?/span>
Gougou
q样的中转站Q不同的标准Q根本无法统计?/span>
在公认的排名中,l别人打分,也有个信用度的问?wbr>。象老白q样德高望重Q品学兼优的人打出来的分数就可靠?wbr>Q小兄弟们打出来的分数就没有那么可靠。所以,在打分之前也涉及?
l文章打分而不是给人打分,q也比较复杂。博?/span>
A
一月
5
博客,篇都是_֓Q博?/span>
B
一月
10
,其中
3
是_֓Q?/span>
7
是他个人的八卦故事Q谁的分数应该高一些?如果是按dQ显?/span>
B
要高Q但?/span>
A
在常理判断上g更有价g些,因ؓ他精品多Q阅d扰却不多
5. Z么没有搞客户端的评h(hun)体系Q?/strong>
原因是客户端太多,如果希望l一太复杂。在q点?wbr>Q我同意王徏的说法Q?a onclick="return top.js.OpenExtLink(window,event,this)" target="_blank">当一件事情有赖于多于一个h的努力才能成功的话,他成功的可能性就
{到一博客大牛们把自q
Blogger Rank
图标象蓝色的
Bloglines
订阅敎ͼl色?/span>
Gougou
订阅Ch在自q博客上,大家又象讨论
Alexa
排名一样ؓq个
Blogger Rank
争论不休。这个时候,才算略有成?/span>
正因虑到这些东西,才写下了q篇文章Q就当作是抛砖引玉吧Q希望看到更多更好的思\?br /> Google SiteMap Protocol是Google自己推出的一U站点地囑֍议,此协议文件基于早期的robots.txt文g协议Qƈ有所升。在Google官方指南中指出加入了Google SiteMap文g的网站将更有利于Google|页爬行机器人的爬行索引Q这样将提高索引|站内容的效率和准确度。文件协议应用了单的XML格式Q一q?个标{,其中关键标签包括链接地址、更新时间、更新频率和索引优先权?/p>
from: http://www.cnblogs.com/shanyou/archive/2006/11/17/564152.aspx
from: http://blog.donews.com/henryhwa/archive/2006/03/29/798355.aspx
q一行定义了此xml文g的命名空_相当于网|件中?lt;html>标签一L(fng)作用?
字符 转义后的字符 HTML字符 字符~码 and(? & & & 单引?/td> ' ' ' 双引?/td> " " " 大于?/td> > > > 于?/td> < < <
q里需注意的是TZDQTZD指定是本地旉区域标记Q像中国是+08:00?
写于Q?002/08 最后更斎ͼ
11/29/2006 17:23:30
Feed Back >> (Read this before you ask question)<q告>
版权声明Q可以Q意{载,转蝲时请务必以超链接形式标明文章原始出处和作者信息及本声?br />http://www.chedong.com/tech/lucene.html
关键词:Lucene java full-text search engine Chinese word segment
内容摘要Q?/p>
Lucene是一个基于Java的全文烦引工具包?/p>
Lucene不是一个完整的全文索引应用Q而是是一个用Java写的全文索引引擎工具包,它可以方便的嵌入到各U应用中实现针对应用的全文烦?索功能?/p>
Lucene的作者:Lucene的A(ch)献?a >Doug Cutting是一位资深全文烦?索专Ӟ曄是V-Twin搜烦引擎(Apple的Copland操作pȝ的成׃一)的主要开发者,后在Excite担Q高pȝ架构设计师,目前从事于一些INTERNET底层架构的研I。他贡献出的Lucene的目标是为各U中型应用E序加入全文索功能?/p>
Lucene的发展历E:早先发布在作者自qwww.lucene.comQ后来发布在SourceForgeQ?001q年底成为APACHE基金会jakarta的一个子目Q?a >http://jakarta.apache.org/lucene/
已经有很多Java目都用了Lucene作ؓ其后台的全文索引引擎Q比较著名的有:
Eclipse:ZJava的开攑ּ发^収ͼ帮助部分的全文烦引用了Lucene
对于中文用户来说Q最兛_的问题是其是否支持中文的全文索。但通过后面对于Lucene的结构的介绍Q你会了解到׃Lucene良好架构设计Q对中文的支持只需对其语言词法分析接口q行扩展p实现对中文检索的支持?/p>
Lucene的API接口设计的比较通用Q输入输出结构都很像数据库的?=>记录==>字段Q所以很多传l的应用的文件、数据库{都可以比较方便的映到Lucene的存储结?接口中。M上看Q可以先?b>Lucene当成一个支持全文烦引的数据库系l?/b>?/p>
比较一下Lucene和数据库Q?/p>
Lucene | 数据?/td> |
索引数据源:doc(field1,field2...) doc(field1,field2...) |
索引数据源:record(field1,field2...) record(field1..) |
DocumentQ一个需要进行烦引的“单元?br />一个Document由多个字D늻?/td> | RecordQ记录,包含多个字段 |
FieldQ字D?/td> | FieldQ字D?/td> |
HitsQ查询结果集Q由匚w的Documentl成 | RecordSetQ查询结果集Q由多个Recordl成 |
全文??like "%keyword%"
通常比较厚的书籍后面常常附关键词索引表(比如Q北京:12, 34,上vQ?,77……)Q它能够帮助读者比较快地找到相兛_容的늠。而数据库索引能够大大提高查询的速度原理也是一P惛_一下通过书后面的索引查找的速度要比一一地d定w多少倍……而烦引之所以效率高Q另外一个原因是它是排好序的?b>对于索系l来说核心是一个排序问?/b>?/p>
׃数据库烦引不是ؓ全文索引设计的,因此Q?b>使用like "%keyword%"Ӟ数据库烦引是不v作用?/b>Q在使用like查询Ӟ搜烦q程又变成类g一页M的遍历过E了Q所以对于含有模p查询的数据库服务来_LIKEҎ(gu)能的危x极大的。如果是需要对多个关键词进行模p匹配:like"%keyword1%" and like "%keyword2%" ...其效率也可惌知了?/p>
所以徏立一个高效检索系l的关键是徏立一个类gU技索引一L(fng)反向索引机制Q将数据源(比如多篇文章Q排序顺序存储的同时Q有另外一个排好序的关键词列表Q用于存储关键词==>文章映射关系Q利用这L(fng)映射关系索引Q[关键?=>出现关键词的文章~号Q出现次敎ͼ甚至包括位置Qv始偏U量Q结束偏U量Q,出现频率]Q检索过E就是把模糊查询变成多个可以利用索引的精查询的逻辑l合的过E?/b>。从而大大提高了多关键词查询的效率,所以,全文索问题归l到最后是一个排序问题?/p>
由此可以看出模糊查询相对数据库的_查询是一个非怸定的问题,q也是大部分数据库对全文索支持有限的原因。Lucene最核心的特征是通过Ҏ(gu)的烦引结构实C传统数据库不擅长的全文烦引机Ӟq提供了扩展接口Q以方便针对不同应用的定制?/p>
可以通过一下表格对比一下数据库的模p查询:
Lucene全文索引引擎 | 数据?/td> | |
索引 | 数据源中的数据都通过全文索引一一建立反向索引 | 对于LIKE查询来说Q数据传l的索引是根本用不上的。数据需要逐个便利记录q行GREP式的模糊匚wQ比有烦引的搜烦速度要有多个数量U的下降?/td> |
匚w效果 | 通过词元(term)q行匚wQ通过语言分析接口的实玎ͼ可以实现对中文等非英语的支持?/td> | 使用Qlike "%net%" 会把netherlands也匹配出来, 多个关键词的模糊匚wQ用like "%com%net%"Q就不能匚w词序颠倒的xxx.net..xxx.com |
匚w?/td> | 有匹配度法Q将匚wE度Q相似度Q比较高的结果排在前面?/td> | 没有匚wE度的控Ӟ比如有记录中net出现5词和出现1ơ的Q结果是一L(fng)?/td> |
l果输出 | 通过特别的算法,最匚w度最高的?00条结果输出,l果集是~冲式的批量读取的?/td> | q回所有的l果集,在匹配条目非常多的时候(比如上万条)需要大量的内存存放q些临时l果集?/td> |
可定制?/td> | 通过不同的语a分析接口实现Q可以方便的定制出符合应用需要的索引规则Q包括对中文的支持) | 没有接口或接口复杂,无法定制 |
l论 | 高负载的模糊查询应用Q需要负责的模糊查询的规则,索引的资料量比较?/td> | 使用率低Q模p匹配规则简单或者需要模p查询的资料量少 |
全文索和数据库应用最大的不同在于Q让
最相关?/span>
?00条结果满?8%以上用户的需?br />
Lucene的创C处:
大部分的搜烦Q数据库Q引擎都是用B?wi)结构来l护索引Q烦引的更新会导致大量的IO操作QLucene在实CQ对此稍微有所改进Q不是维护一个烦引文Ӟ而是在扩展烦引的时候不断创建新的烦引文Ӟ然后定期的把q些新的烦引文件合q到原先的大索引中(针对不同的更新策略,Ҏ(gu)的大可以调_Q这样在不媄响检索的效率的前提下Q提高了索引的效率?/p>
Lucene和其他一些全文检索系l?应用的比较:
Lucene | 其他开源全文检索系l?/td> | |
增量索引和批量烦?/td> | 可以q行增量的烦?Append)Q可以对于大量数据进行批量烦引,q且接口设计用于优化扚w索引和小扚w的增量烦引?/td> | 很多pȝ只支持批量的索引Q有时数据源有一点增加也需要重建烦引?/td> |
数据?/td> | Lucene没有定义具体的数据源Q而是一个文档的l构Q因此可以非常灵zȝ适应各种应用Q只要前端有合适的转换器把数据源{换成相应l构Q, | 很多pȝ只针对网,~Z其他格式文档的灵zL?/td> |
索引内容抓取 | Lucene的文档是由多个字D늻成的Q甚臛_以控刉些字D需要进行烦引,那些字段不需要烦引,q一步烦引的字段也分为需要分词和不需要分词的cdQ?br /> 需要进行分词的索引Q比如:标题Q文章内容字D?br /> 不需要进行分词的索引Q比如:作?日期字段 | ~Z通用性,往往文档整个烦引了 |
语言分析 | 通过语言分析器的不同扩展实现Q?br />可以qo掉不需要的词:an the of {, 西文语法分析Q将jumps jumped jumper都归l成jumpq行索引/?br />非英文支持:对亚z语aQ阿拉伯语言的烦引支?/td> | ~Z通用接口实现 |
查询分析 | 通过查询分析接口的实玎ͼ可以定制自己的查询语法规则: 比如Q?多个关键词之间的 + - and or关系{?/td> | |
q发讉K | 能够支持多用L(fng)使用 |
对于中文来说Q全文烦引首先还要解决一个语a分析的问题,对于英文来说Q语句中单词之间是天焉过I格分开的,但亚z语a的中日韩文语句中的字是一个字挨一个,所有,首先要把语句中按“词”进行烦引的话,q个词如何切分出来就是一个很大的问题?/p>
首先Q肯定不能用单个字符?si-gram)为烦引单元,否则查“上”时Q不能让含有“v上”也匚w?/p>
但一句话Q“北京天安门”,计算机如何按照中文的语言?fn)惯q行切分呢?
“北?天安门?q是“北 ?天安门”?让计机能够按照语言?fn)惯q行切分Q往往需要机器有一个比较丰富的词库才能够比较准的识别句中的单词?/p>
另外一个解决的办法是采用自动切分算法:单词按?元语?bigram)方式切分出来Q比如:
"北京天安? ==> "北京 京天 天安 安门"?/p>
q样Q在查询的时候,无论是查?北京" q是查询"天安?Q将查询词组按同L(fng)规则q行切分Q?北京"Q?天安安门"Q多个关键词之间按与"and"的关pȝ合,同样能够正确地映到相应的烦引中。这U方式对于其他亚z语aQ韩文,日文都是通用的?/p>
Z自动切分的最大优Ҏ(gu)没有词表l护成本Q实现简单,~点是烦引效率低Q但对于中小型应用来_Z2元语法的切分q是够用的。基?元切分后的烦引一般大和源文件差不多Q而对于英文,索引文g一般只有原文g?0%-40%不同Q?/p>
|
自动切分 | 词表切分 |
实现 | 实现非常?/td> | 实现复杂 |
查询 | 增加了查询分析的复杂E度Q?/td> | 适于实现比较复杂的查询语法规?/td> |
存储效率 | 索引冗余大,索引几乎和原文一样大 | 索引效率高,为原文大的30Q左?/td> |
l护成本 | 无词表维护成?/td> | 词表l护成本非常高:中日韩等语言需要分别维护?br />q需要包括词频统计等内容 |
适用领域 | 嵌入式系l:q行环境资源有限 分布式系l:无词表同步问?br />多语a环境Q无词表l护成本 |
Ҏ(gu)询和存储效率要求高的专业搜烦引擎 |
目前比较大的搜烦引擎的语a分析法一般是Z以上2个机制的l合。关于中文的语言分析法Q大家可以在Google查关键词"wordsegment search"能找到更多相关的资料?/p>
下蝲Q?a >http://jakarta.apache.org/lucene/
注意QLucene中的一些比较复杂的词法分析是用JavaCC生成的(JavaCCQJavaCompilerCompilerQ纯Java的词法分析生成器Q,所以如果从源代码编译或需要修改其中的QueryParser、定制自q词法分析器,q需要从https://javacc.dev.java.net/下蝲javacc?/p>
lucene的组成结构:对于外部应用来说索引模块(index)和检索模?search)是主要的外部应用入口
org.apache.Lucene.search/ | 搜烦入口 |
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的用方法:
索引q程Q从命o行读取文件名Q多个)Q将文g分\?path字段)和内?body字段)2个字D进行存储,q对内容q行全文索引Q烦引的单位是Document对象Q每个Document对象包含多个字段Field对象Q针对不同的字段属性和数据输出的需求,对字D还可以选择不同的烦?存储字段规则Q列表如下:Ҏ(gu) | 切词 | 索引 | 存储 | 用?/th> |
---|---|---|---|---|
Field.Text(String name, String value) | Yes | Yes | Yes | 切分词烦引ƈ存储Q比如:标题Q内容字D?/td> |
Field.Text(String name, Reader value) | Yes | Yes | No | 切分词烦引不存储Q比如:META信息Q?br />不用于返回显C,但需要进行检索内?/td> |
Field.Keyword(String name, String value) | No | Yes | Yes | 不切分烦引ƈ存储Q比如:日期字段 |
Field.UnIndexed(String name, String value) | No | No | Yes | 不烦引,只存储,比如Q文件\?/td> |
Field.UnStored(String name, String value) | Yes | Yes | No | 只全文烦引,不存?/td> |
public class IndexFiles {
//使用Ҏ(gu)Q? IndexFiles [索引输出目录] [索引的文件列表] ...
public static void main(String[] args) throws Exception {
String indexPath = args[0];
IndexWriter writer;
//用指定的语言分析器构造一个新的写索引器(W?个参数表C是否ؓ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进行全文烦引,q存?br /> Document doc = new Document();
doc.add(Field.UnIndexed("path", args[i]));
doc.add(Field.Text("body", (Reader) new InputStreamReader(is)));
//文档写入烦?br /> writer.addDocument(doc);
is.close();
};
//关闭写烦引器
writer.close();
}
}
索引q程中可以看刎ͼ
索过E和l果昄Q?/p>
搜烦l果q回的是Hits对象Q可以通过它再讉KDocument==>Field中的内容?/p>
假设Ҏ(gu)body字段q行全文索,可以查询结果的path字段和相应查询的匚w?score)打印出来Q?/p>
public class Search {在整个检索过E中Q语a分析器,查询分析器,甚至搜烦器(SearcherQ都是提供了抽象的接口,可以Ҏ(gu)需要进行定制?
public static void main(String[] args) throws Exception {
String indexPath = args[0], queryString = args[1];
//指向索引目录的搜索器
Searcher searcher = new IndexSearcher(indexPath);
//查询解析器:使用和烦引同L(fng)语言分析?br /> Query query = QueryParser.parse(queryString, "body",
new SimpleAnalyzer());
//搜烦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));
};
}
}
化的查询分析?/b>
个h感觉lucene成ؓJAKARTA目后,d了太多的旉用于调试日趋复杂QueryParserQ而其中大部分是大多数用户q不很熟(zhn)的Q目前LUCENE支持的语法:
Query ::= ( Clause )*
Clause ::= ["+", "-"] [<TERM> ":"] ( <TERM> | "(" Query ")")
中间的逻辑包括Qand or + - &&||{符P而且q有"短语查询"和针对西文的前缀/模糊查询{,个h感觉对于一般应用来_q些功能有一些华而不实,其实能够实现目前cM于Google的查询语句分析功能其实对于大多数用户来说已经够了。所以,Lucene早期版本的QueryParser仍是比较好的选择?/p>
d修改删除指定记录QDocumentQ?/b>
Lucene提供了烦引的扩展机制Q因此烦引的动态扩展应该是没有问题的,而指定记录的修改也似乎只能通过记录的删除,然后重新加入实现。如何删除指定的记录呢?删除的方法也很简单,只是需要在索引时根据数据源中的记录ID专门另徏索引Q然后利用IndexReader.delete(Termterm)Ҏ(gu)通过q个记录ID删除相应的Document?/p>
Ҏ(gu)某个字段值的排序功能
lucene~省是按照自q相关度算法(scoreQ进行结果排序的Q但能够Ҏ(gu)其他字段q行l果排序是一个在LUCENE的开发邮件列表中l常提到的问题,很多原先Z数据库应用都需要除了基于匹配度QscoreQ以外的排序功能。而从全文索的原理我们可以了解刎ͼM不基于烦引的搜烦q程效率都会D效率非常的低Q如果基于其他字D늚排序需要在搜烦q程中访问存储字D,速度回大大降低,因此非常是不可取的?/p>
但这里也有一个折中的解决Ҏ(gu)Q在搜烦q程中能够媄响排序结果的只有索引中已l存储的docID和scoreq?个参敎ͼ所以,Zscore以外的排序,其实可以通过数据源预先排好序,然后Ҏ(gu)docIDq行排序来实现。这样就避免了在LUCENE搜烦l果外对l果再次q行排序和在搜烦q程中访问不在烦引中的某个字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果命中列表中:
* hq.put(new ScoreDoc(doc, score)); // update hit queue
* 如果用doc ?1/doc 代替 scoreQ就实现了根据docID排或逆排
* 假设数据源烦引时已经按照某个字段排好了序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惛_使用一个标准的中间格式作ؓLucene的数据导入接口,然后其他数据Q比如PDF只需要通过解析器{换成标准的中间格式就可以q行数据索引了。这个中间格式主要以XMLZQ类似实现已l不?Q?个:
数据? WORD PDF HTML DB other
\ | | | /
XML中间格式
|
Lucene INDEX
目前q没有针对MSWord文档的解析器Q因为Word文档和基于ASCII的RTF文档不同Q需要用COM对象机制解析。这个是我在Google上查的相兌料: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去索引都重新进行一ơ烦引文件的写入操作Q文件I/O是一仉常消耗资源的事情Q?/p>
Lucene先在内存中进行烦引操作,q根据一定的扚wq行文g的写入。这个批ơ的间隔大Q文件的写入ơ数少Q但占用内存会很多。反之占用内存少Q但文gIO操作频繁Q烦引速度会很慢。在IndexWriter中有一个MERGE_FACTOR参数可以帮助你在构造烦引器后根据应用环境的情况充分利用内存减少文g的操作。根据我的用经验:~省Indexer是每20条记录烦引后写入一ơ,每将MERGE_FACTOR增加50倍,索引速度可以提高1倍左叟?br />
搜烦q程优化
lucene支持内存索引Q这L(fng)搜烦比基于文件的I/O有数量的速度提升?br />http://www.onjava.com/lpt/a/3273
而尽可能减少IndexSearcher的创建和Ҏ(gu)索结果的前台的缓存也是必要的?br />
Lucene面向全文索的优化在于首次索引索后Qƈ不把所有的记录QDocumentQ具体内容读取出来,而v只将所有结果中匚w度最高的?00条结果(TopDocsQ的ID攑ֈl果集缓存中q返回,q里可以比较一下数据库索:如果是一?0,000条的数据库检索结果集Q数据库是一定要把所有记录内定w取得以后再开始返回给应用l果集的。所以即使检索匹配L很多QLucene的结果集占用的内存空间也不会很多。对于一般的模糊索应用是用不到这么多的结果的Q头100条已l可以满?0%以上的检索需求?br />
如果首批~存l果数用完后q要d更后面的l果时Searcher会再ơ检索ƈ生成一个上ơ的搜烦~存数大1倍的~存Qƈ再重新向后抓取。所以如果构造一个SearcherL1Q?20条结果,Searcher其实是进行了2ơ搜索过E:?00条取完后Q缓存结果用完,Searcher重新索再构造一?00条的l果~存Q依此类推,400条缓存,800条缓存。由于每ơSearcher对象消失后,q些~存也访问那不到了,你有可能惛_l果记录~存下来Q缓存数量保证?00以下以充分利用首ơ的l果~存Q不让Lucene费多次索,而且可以分q行l果~存?br />
Lucene的另外一个特Ҏ(gu)在收集结果的q程中将匚w度低的结果自动过滤掉了。这也是和数据库应用需要将搜烦的结果全部返回不同之处?/p>
我的一些尝?/a>Q?/p> Luene的确是一个面对对象设计的典范 q些优点都是非常值得在以后的开发中学习(fn)借鉴的。作Z个通用工具包,Lunece的确l予了需要将全文索功能嵌入到应用中的开发者很多的便利?/p> 此外Q通过对Lucene的学?fn)和使用Q我也更深刻地理解了Z么很多数据库优化设计中要求,比如Q?/p> 参考资料: Apache: Lucene Project The Lucene search engine: Powerful, flexible, and free Lucene Tutorial Notes on distributed searching with Lucene 中文语言的切分词 搜烦引擎工具介绍 Lucene作者Cutting的几论文和专利 Lucene?NET实现QdotLucene Lucene作者Cutting的另外一个项目:ZJava的搜索引擎Nutch 关于Z词表和N-Gram的切分词比较 特别感谢Q?br />前网易CTO许良?Jack Xu)l我的指|是?zhn)我带入了搜索引擎这个行业?/p>原文出处Q?lt;a>http://www.chedong.com/tech/lucene.html</a>
http://jakarta.apache.org/lucene/
Lucene开?用户邮g列表归档
Lucene-dev@jakarta.apache.org
Lucene-user@jakarta.apache.org
http://www.javaworld.com/javaworld/jw-09-2000/jw-0915-Lucene_p.html
http://www.darksleep.com/puff/lucene/lucene.html
http://home.clara.net/markharwood/lucene/
http://www.google.com/search?sourceid=navclient&hl=zh-CN&q=chinese+word+segment
http://searchtools.com/
http://lucene.sourceforge.net/publications.html
http://sourceforge.net/projects/dotlucene/
http://www.nutch.org/ http://sourceforge.net/projects/nutch/
http://china.nikkeibp.co.jp/cgi-bin/china/news/int/int200302100112.html
2005-01-08 Cutting在Pisa大学做的关于Lucene的讲座:非常详细的Lucene架构解说
from:
概述Q?br />
假设?个schemaQS1和S2。我们要为S1里每一个元素在S2中找到匹配的元素?br /> q程如下Q?br /> 1. G1 = SQL2Graph(S1); G2 = SQL2Graph(S2); 把schema变成图,N用了Open Information Model (OIM)规格Q图中node采用矩Ş和卵形,矩Ş是文字描qͼ卵Ş是标识符
2. initialMap = StringMatch(G1, G2); 用字W串匚w做ؓ初始匚wQ主要是比较通常的前~和后~Q这L(fng)l果通常是不准确?br />
3. product = SFJoin(G1, G2, initialMap); 用SF法生成l果?font color="#0000ff">假设两个不同的节Ҏ(gu)怼的,则它们邻接元素的怼度增加。经q一pd的P代,q种怼度会传遍整个?br />
4. result = SelectThreshold(product); l果{?br />
SF法
图中的每条边Q用一个三元组表示QsQpQoQ,分别?源点Q边名,目的炏V?br />
怼度传播图Q首先定义pairwise connectivity graph(PCG) Q?((x; y); p; (x'; y')) 属于 PCG(A;B)<==>(x; p; x') ?A and (y; p; y') ?B?关键是p要相同,也就是边的名字一栗?/font>式子从右向左推导Q就可以A、B从两个模型徏立v它们的PCG?/font>图中的每个节点,都是A和B中的元素构成?元组Q叫做map pairs?br /> induced propagation graph。从PCG推导而来Q加上了反向的边Q边上注明了[传播pL]Qgؓ 1/nQn为相应的边的数目?br /> 不动点计:
设?x; y) > 0 代表了节点x ?A ?y ?B 的相似度Q是在整个 A X B的范围上定义的。我们把 Q(mo) 叫做 mapping。相似度的计就是基于?values的P代计。设 Q(mo)i 代表了第 i ơP代后的结果,Q(mo)0 是初始相似度Q可以用字符串相似度的办法的得出Q在我们的例子里Q没?Q(mo)0 Q即?Q(mo)0 =1Q?br /> 每次q代中,Q(mo)-values 都会Ҏ(gu)光居paris?Q(mo)-values 乘以[传播pL] 来增加。例如,在第一ơP?Q(mo)1(a1; b1) = Q(mo)0(a1; b1) + Q(mo)0(a; b) * 0.5 = 1.5。类似的Q?sup>1(a, b) = Q(mo)0(a, b) + Q(mo)0(a1; b1) * 1.0 + Q(mo)0(a2, b1) *1.0 = 3.0。接下来Q所?Q(mo) D行正规化Q比如除以当前P代的 Q(mo)的最大|保证所?Q(mo) 都不大于1。所以在正规化以后,Q(mo)1(a; b) = 1.0, Q(mo)1(a1, b1) = 1.5/3.0 = 0.5。一般情况下QP代如下进行:
上面的计进行P代,直到 Q(mo)n ?Q(mo)n-1之间的差别小于一个阈|如果计算没有聚合Q我们就在P代超q一定次数后停止。上?的第三副图,是5ơP代后的结果。表3时一些计方法,后面的实验表明,C比较好。A叫做 sparceQB叫做 exceptedQC叫做verbose
qo
q代出的l果是一U[多匹配]Q可能包含有用的匚w子集?br /> 三个步骤Q?br /> 1。用E序定义的[限制条g]q行qo?br /> 2。用双向图中的匹配上下文技术进行过?br /> 3。比较各U技术的有效性(满用户需求的能力Q?br /> 限制Q主要有两种Q一个是[cd]限制Q比如只考虑[列]的匹配(匚w双方都是列)。第二个?cardinality 限制Q即模式S1中的所有元素都要在S2中有一个映?br />
stable marriage问题Qn奛_n男配对,不存在这L(fng)两对 (x; y)?x0; y0)Q其中x喜欢 y0 胜过 yQ而且 y0 喜欢 x 胜过 x0。具有stable marriage的匹配结果的total satisfaction可能会比不具有stable marriage的匹配结果还低!
匚w质量的评?br />
基本的评估思想Q就是?用户对匹配结果做的修改越,匚w质量p高(修改l果包括L错误的pairQ加上正的pairQ?br /> n是找到的匚w敎ͼm是理想的匚w敎ͼc是用户作Z正的数目?br />
from: http://www.cnblogs.com/anf/archive/2006/08/15/477700.html
......
destUrl="http://www.ebook.com/java/|络~程001.zip";
url = new URL(destUrl);
httpUrl = (HttpURLConnection) url.openConnection();
//q接指定的网l资?br />httpUrl.connect();
//获取|络输入?br />bis = new BufferedInputStream(httpUrl.getInputStream());
......
//讄代理服务?br />System.getProperties().put("proxySet", "true");
System.getProperties().put("proxyHost", "10.154.134.110");
System.getProperties().put("proxyPort", "8080");
......
fos = new FileOutputStream(fileName);
if (this.DEBUG)
System.out.println("正在获取链接[" + destUrl + "]的内?..\n其保存为文件[" + fileName +"]");
//保存文g
while ( (size = bis.read(buf)) != -1)
fos.write(buf, 0, size);
......
import java.io.*;
import java.net.*;
import java.util.*;
/**
* QpQTitle: 个h开发的APIQ?pQ?br />* QpQDescription: 指定的HTTP|络资源在本C文g形式存放Q?pQ?br />* QpQCopyright: Copyright (c) 2004Q?pQ?br />* QpQCompany: NewSkyQ?pQ?br />* @author MagicLiao
* @version 1.0
*/
public class HttpGet {
public final static boolean DEBUG = true;//调试?br /> private static int BUFFER_SIZE = 8096;//~冲区大?br /> private Vector vDownLoad = new Vector();//URL列表
private Vector vFileList = new Vector();//下蝲后的保存文g名列?br />
/**
* 构造方?br /> */
public HttpGet() {}
/**
* 清除下蝲列表
*/
public void resetList() {
vDownLoad.clear();
vFileList.clear();
}
/**
* 增加下蝲列表?br /> *
* @param url String
* @param filename String
*/
public void addItem(String url, String filename) {
vDownLoad.add(url);
vFileList.add(filename);
}
/**
* Ҏ(gu)列表下蝲资源
*/
public void downLoadByList() {
String url = null;
String filename = null;
//按列表顺序保存资?br /> for (int i = 0; i Q?vDownLoad.size(); i++) {
url = (String) vDownLoad.get(i);
filename = (String) vFileList.get(i);
try {
saveToFile(url, filename);
}
catch (IOException err) {
if (DEBUG) {
System.out.println("资源[" + url + "]下蝲p|!!!");
}
}
}
if (DEBUG) {
System.out.println("下蝲完成!!!");
}
}
/**
* HTTP资源另存为文?br />*
* @param destUrl String
* @param fileName String
* @throws Exception
*/
public void saveToFile(String destUrl, String fileName) throws IOException {
FileOutputStream fos = null;
BufferedInputStream bis = null;
HttpURLConnection httpUrl = null;
URL url = null;
byte[] buf = new byte[BUFFER_SIZE];
int size = 0;
//建立链接
url = new URL(destUrl);
httpUrl = (HttpURLConnection) url.openConnection();
//q接指定的资?br /> httpUrl.connect();
//获取|络输入?br /> bis = new BufferedInputStream(httpUrl.getInputStream());
//建立文g
fos = new FileOutputStream(fileName);
if (this.DEBUG)
System.out.println("正在获取链接[" + destUrl + "]的内?..\n其保存为文件[" + fileName + "]");
//保存文g
while ( (size = bis.read(buf)) != -1)
fos.write(buf, 0, size);
fos.close();
bis.close();
httpUrl.disconnect();
}
/**
* 讄代理服务?br />*
* @param proxy String
* @param proxyPort String
*/
public void setProxyServer(String proxy, String proxyPort) {
//讄代理服务?
System.getProperties().put("proxySet", "true");
System.getProperties().put("proxyHost", proxy);
System.getProperties().put("proxyPort", proxyPort);
}
/**
* 讄认证用户名与密码
*
* @param uid String
* @param pwd String
*/
public void setAuthenticator(String uid, String pwd) {
Authenticator.setDefault(new MyAuthenticator(uid, pwd));
}
/**
* L?用于试)
*
* @param argv String[]
*/
public static void main(String argv[]) {
HttpGet oInstance = new HttpGet();
try {
//增加下蝲列表Q此处用户可以写入自׃码来增加下蝲列表Q?br /> oInstance.addItem("http://www.ebook.com/java/|络~程001.zip","./|络~程1.zip");
oInstance.addItem("http://www.ebook.com/java/|络~程002.zip","./|络~程2.zip");
oInstance.addItem("http://www.ebook.com/java/|络~程003.zip","./|络~程3.zip");
oInstance.addItem("http://www.ebook.com/java/|络~程004.zip","./|络~程4.zip");
oInstance.addItem("http://www.ebook.com/java/|络~程005.zip","./|络~程5.zip");
oInstance.addItem("http://www.ebook.com/java/|络~程006.zip","./|络~程6.zip");
oInstance.addItem("http://www.ebook.com/java/|络~程007.zip","./|络~程7.zip");
//开始下?br /> oInstance.downLoadByList();
}
catch (Exception err) {
System.out.println(err.getMessage());
}
}
}
from: http://www.1-100.org/other/11548.htm