﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-weidagang2046的专栏-文章分类-Search Engine</title><link>http://www.blogjava.net/weidagang2046/category/17361.html</link><description>物格而后知致</description><language>zh-cn</language><lastBuildDate>Wed, 28 Feb 2007 04:35:17 GMT</lastBuildDate><pubDate>Wed, 28 Feb 2007 04:35:17 GMT</pubDate><ttl>60</ttl><item><title>Blogger Rank</title><link>http://www.blogjava.net/weidagang2046/articles/91368.html</link><dc:creator>weidagang2046</dc:creator><author>weidagang2046</author><pubDate>Tue, 02 Jan 2007 05:47:00 GMT</pubDate><guid>http://www.blogjava.net/weidagang2046/articles/91368.html</guid><wfw:comment>http://www.blogjava.net/weidagang2046/comments/91368.html</wfw:comment><comments>http://www.blogjava.net/weidagang2046/articles/91368.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weidagang2046/comments/commentRss/91368.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weidagang2046/services/trackbacks/91368.html</trackback:ping><description><![CDATA[
		<div style="DIRECTION: ltr">
				<span lang="ZH-CN">写博客就要写的短小精悍，逻辑清晰，太长的博客基本上没人看<wbr></wbr>，又长又枯燥的博客就更没有人看了。</span>
				<span lang="EN-US">
				</span>
				<span lang="ZH-CN">我估计<a onclick="return top.js.OpenExtLink(window,event,this)" href="http://blog.donews.com/laobai" target="_blank">老白</a>是少数有毅力能够把我的博客读完的人之一。有此份毅力，何事不成<wbr></wbr>。所以，老白也是我敬仰敬重的人。</span>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">
						<span>不过谈到这个排名和打分问题，咱哥们儿还是应该在一起</span>
						<span style="FONT-FAMILY: SimSun">合计合计这个事儿</span>
						<span>：</span>
				</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="MARGIN-TOP: 0px; FONT-SIZE: 10pt; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle">
						<strong>1. 为什么要搞公共排名，而不是个人排名？</strong>
				</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">
						<span lang="ZH-CN">个人排名，读了<a onclick="return top.js.OpenExtLink(window,event,this)" href="http://blog.donews.com/laobai/archive/2006/03/28/796722.aspx" target="_blank">老白的文章</a>之后，才理解这是一个个人知识管理的问题。其实绝大多数人并不订阅<wbr></wbr>那么多博客，他们每天读读 </span>
						<span lang="EN-US">Keso</span>
						<span lang="ZH-CN">和老白的网摘，在到</span>
						<span lang="EN-US">365key</span>
						<span lang="ZH-CN">和</span>
						<span lang="EN-US">donews</span>
						<span lang="ZH-CN">的主页上转一圈，基本就不会漏掉什么重要内容。如果这仅仅是老白等<wbr></wbr>少数人的困扰，那方法就很多了，大不了老白自己手工统计一下<wbr></wbr>，辛苦老白一个，能造福千万人。 </span>
				</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">谈到打分，更是这样，没有排名和比较，分数就没有意义<wbr></wbr>。老白其实也可以根据自己心中的分数搞出来一个老白阅读榜<wbr></wbr>，和胡润财富榜一样成为大家阅读博客的重要参照依据。</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">
						<span lang="ZH-CN">我没有老白和</span>
						<span lang="EN-US">Keso</span>
						<span lang="ZH-CN">这样大的影响力，也没有许多时间来一一甄别和评判众多博客<wbr></wbr>，只好和大家一样，要么期盼老白或者</span>
						<span lang="EN-US"> Keso</span>
						<span lang="ZH-CN">能够搞出来一个，要么就跟跟潮流，看看有没有社会化评价的体系和方<wbr></wbr>法。</span>
				</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="MARGIN-TOP: 0px; FONT-SIZE: 10pt; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle">
						<strong>2. 为什么没有使用页面访问量？</strong>
				</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">
						<span lang="ZH-CN">这个东西太容易造假，而且不能反映博客的水平和质量<wbr></wbr>。常在互联网混的小兄弟们虽然没有徐博客那样的明星出生<wbr></wbr><script type="text/javascript"><![CDATA[lt;!--D(["mb","，但是想要搞点页面访问量，先不说那些技术手段，还是有其他许多方&lt;WBR&gt;法：起一些危言耸听或者吸引眼球的标题；贴些带擦边球的图片&lt;WBR&gt;；经常专注一下百度和新浪搜索排前几名的关键字；经常转载一些从\n&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;ChinaBBS&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;，&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Qihoo&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;上来的热门贴。博客可以搞的臭气熏天，页面访问量倒也可以同步增长&lt;WBR&gt;。回复数，\n&lt;/span&gt;&lt;span lang\u003d\"EN-US\" style\u003d\"font-family:Verdana\"&gt;TrackBack&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;因为&lt;/span&gt;&lt;span lang\u003d\"EN-US\" style\u003d\"font-family:Verdana\"&gt;SPAM&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;\n的原因同样不太可靠。&lt;/span&gt;&lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt; &lt;/p&gt;\n&lt;div style\u003d\"margin-top:0px;font-size:10pt;margin-bottom:0px;vertical-align:middle\"&gt;&lt;strong&gt;3. 为什么没有使用订阅数？&lt;/strong&gt;&lt;/div&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt; &lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt;没有使用订阅者倒不是因为担心造假，这个问题比较复杂。&lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt; &lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt;&lt;span lang\u003d\"ZH-CN\"&gt;仅有订阅数是不足以表明博客的价值。比如，有两个&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Blogger&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;：&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;A&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;\n和&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;B&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;。&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;A&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;有&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;10&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;个订阅者，&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;B&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;\n有&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;15&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;个订阅者，能简单的说&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;B&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;就比&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;A&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;更有价值吗？如果说&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;A&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;\n的订阅者都是象老白，&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Keso&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;这样的大牛，而&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;B&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;的订阅者都是自己刚开始写博客的小兄弟们，&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;A&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;和&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;\nB&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;的价值那个高？这就很难说了。&lt;/span&gt;&lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt; &lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt;&lt;span lang\u003d\"ZH-CN\"&gt;所以&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Blogger&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;有没有价值还要看订阅者的权值。这样的话，问题就来了。凭什么说&lt;WBR&gt;，老白的权值是&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;\n100&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;，&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Keso&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;的权值也是&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;",1]);//--&gt;]]&gt;</script>
 ，但是想要搞点页面访问量，先不说那些技术手段，还是有其他许多方<wbr></wbr>法：起一些危言耸听或者吸引眼球的标题；贴些带擦边球的图片<wbr></wbr>；经常专注一下百度和新浪搜索排前几名的关键字；经常转载一些从 </span>
						<span lang="EN-US">ChinaBBS</span>
						<span lang="ZH-CN">，</span>
						<span lang="EN-US">Qihoo</span>
						<span lang="ZH-CN">上来的热门贴。博客可以搞的臭气熏天，页面访问量倒也可以同步增长<wbr></wbr>。回复数， </span>
						<span lang="EN-US" style="FONT-FAMILY: Verdana">TrackBack</span>
						<span lang="ZH-CN">因为</span>
						<span lang="EN-US" style="FONT-FAMILY: Verdana">SPAM</span>
						<span lang="ZH-CN"> 的原因同样不太可靠。</span>
				</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<div style="MARGIN-TOP: 0px; FONT-SIZE: 10pt; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle">
						<strong>3. 为什么没有使用订阅数？</strong>
				</div>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">没有使用订阅者倒不是因为担心造假，这个问题比较复杂。</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">
						<span lang="ZH-CN">仅有订阅数是不足以表明博客的价值。比如，有两个</span>
						<span lang="EN-US">Blogger</span>
						<span lang="ZH-CN">：</span>
						<span lang="EN-US">A</span>
						<span lang="ZH-CN"> 和</span>
						<span lang="EN-US">B</span>
						<span lang="ZH-CN">。</span>
						<span lang="EN-US">A</span>
						<span lang="ZH-CN">有</span>
						<span lang="EN-US">10</span>
						<span lang="ZH-CN">个订阅者，</span>
						<span lang="EN-US">B</span>
						<span lang="ZH-CN"> 有</span>
						<span lang="EN-US">15</span>
						<span lang="ZH-CN">个订阅者，能简单的说</span>
						<span lang="EN-US">B</span>
						<span lang="ZH-CN">就比</span>
						<span lang="EN-US">A</span>
						<span lang="ZH-CN">更有价值吗？如果说</span>
						<span lang="EN-US">A</span>
						<span lang="ZH-CN"> 的订阅者都是象老白，</span>
						<span lang="EN-US">Keso</span>
						<span lang="ZH-CN">这样的大牛，而</span>
						<span lang="EN-US">B</span>
						<span lang="ZH-CN">的订阅者都是自己刚开始写博客的小兄弟们，</span>
						<span lang="EN-US">A</span>
						<span lang="ZH-CN">和</span>
						<span lang="EN-US"> B</span>
						<span lang="ZH-CN">的价值那个高？这就很难说了。</span>
				</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">
						<span lang="ZH-CN">所以</span>
						<span lang="EN-US">Blogger</span>
						<span lang="ZH-CN">有没有价值还要看订阅者的权值。这样的话，问题就来了。凭什么说<wbr></wbr>，老白的权值是</span>
						<span lang="EN-US"> 100</span>
						<span lang="ZH-CN">，</span>
						<span lang="EN-US">Keso</span>
						<span lang="ZH-CN">的权值也是</span>
						<span lang="EN-US">
								<script type="text/javascript"><![CDATA[lt;!--D(["mb","100&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;，而小兄弟的权值就只有&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;1&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;呢？这里的依据是什么？老白肯定认为与小兄弟相比&lt;WBR&gt;，自己的权值应该是\n&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;1000&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;，因为他的订阅者都是象&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;keso&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;这样的大牛，你看连&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;keso&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;都说老白的文章是要认真对待的。自己的值应该是&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;\nKeso&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;这群大牛的加权平均值。可是&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Keso&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;的值从什么地方来呢？他的订阅者中也有老白啊。这不就变成了死循环&lt;WBR&gt;了吗？&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Page Rank&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;的贡献就在这里：他先假设所有人初始权值都是相同的&lt;WBR&gt;，每增加一个人订阅或者链接就增加一份权值，这样通过反复叠代&lt;WBR&gt;，就能够收敛到最终的权值。\n&lt;/span&gt;&lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt; &lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt;&lt;span lang\u003d\"ZH-CN\"&gt;这个思路不仅仅能用在网页链接的排名上，同样还可以用在订阅关系和&lt;WBR&gt;博客之间的相互链接上。不过最近有人告诉我，以色列数学家找出了&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Page Rank&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;\n的缺陷，认为&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;PR&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;算法没有考虑页面的更新程度，一旦一个页面被一个&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;PR&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;值高的页面链接了，那就一劳永逸了，不用更新也能保持很高的&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;PR&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;值。有兴趣的人可以参看一下\n&lt;a href\u003d\"http://www2.mta.ac.il/~hillel/data_mining/faults_of_PageRank.pdf\" target\u003d\"_blank\" onclick\u003d\"return top.js.OpenExtLink(window,event,this)\"&gt;这里&lt;/a&gt;。我们在此略过不表。&lt;/span&gt; &lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt; &lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt;&lt;span lang\u003d\"ZH-CN\"&gt;如果使用了类似&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;PR&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;算法的订阅数，这个可行吗？基本上还是不可行的，因为&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Blogger&lt;/span&gt;\n&lt;span lang\u003d\"ZH-CN\"&gt;是无法知道自己的博客被多少人订阅和观看的，不同的客户端&lt;WBR&gt;，还有许多象&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Bloglines&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;，&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Gougou&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;这样的中转站，不同的标准，根本无法统计。&lt;/span&gt;&lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt; &lt;/p&gt;\n&lt;div style\u003d\"margin-top:0px;font-size:10pt;margin-bottom:0px;vertical-align:middle\"&gt;&lt;strong&gt;4. 为什么没有给别人打分呢？&lt;/strong&gt;&lt;/div&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt; &lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt;在公认的排名中，给别人打分，也有个信用度的问题&lt;WBR&gt;。象老白这样德高望重，品学兼优的人打出来的分数就可靠些&lt;WBR&gt;，小兄弟们打出来的分数就没有那么可靠。所以，在打分之前也涉及到",1]);//--&gt;]]&gt;</script>
 100</span>
						<span lang="ZH-CN">，而小兄弟的权值就只有</span>
						<span lang="EN-US">1</span>
						<span lang="ZH-CN">呢？这里的依据是什么？老白肯定认为与小兄弟相比<wbr></wbr>，自己的权值应该是 </span>
						<span lang="EN-US">1000</span>
						<span lang="ZH-CN">，因为他的订阅者都是象</span>
						<span lang="EN-US">keso</span>
						<span lang="ZH-CN">这样的大牛，你看连</span>
						<span lang="EN-US">keso</span>
						<span lang="ZH-CN">都说老白的文章是要认真对待的。自己的值应该是</span>
						<span lang="EN-US"> Keso</span>
						<span lang="ZH-CN">这群大牛的加权平均值。可是</span>
						<span lang="EN-US">Keso</span>
						<span lang="ZH-CN">的值从什么地方来呢？他的订阅者中也有老白啊。这不就变成了死循环<wbr></wbr>了吗？</span>
						<span lang="EN-US">Page Rank</span>
						<span lang="ZH-CN">的贡献就在这里：他先假设所有人初始权值都是相同的<wbr></wbr>，每增加一个人订阅或者链接就增加一份权值，这样通过反复叠代<wbr></wbr>，就能够收敛到最终的权值。 </span>
				</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">
						<span lang="ZH-CN">这个思路不仅仅能用在网页链接的排名上，同样还可以用在订阅关系和<wbr></wbr>博客之间的相互链接上。不过最近有人告诉我，以色列数学家找出了</span>
						<span lang="EN-US">Page Rank</span>
						<span lang="ZH-CN"> 的缺陷，认为</span>
						<span lang="EN-US">PR</span>
						<span lang="ZH-CN">算法没有考虑页面的更新程度，一旦一个页面被一个</span>
						<span lang="EN-US">PR</span>
						<span lang="ZH-CN">值高的页面链接了，那就一劳永逸了，不用更新也能保持很高的</span>
						<span lang="EN-US">PR</span>
						<span lang="ZH-CN">值。有兴趣的人可以参看一下 <a onclick="return top.js.OpenExtLink(window,event,this)" href="http://www2.mta.ac.il/~hillel/data_mining/faults_of_PageRank.pdf" target="_blank">这里</a>。我们在此略过不表。</span> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">
						<span lang="ZH-CN">如果使用了类似</span>
						<span lang="EN-US">PR</span>
						<span lang="ZH-CN">算法的订阅数，这个可行吗？基本上还是不可行的，因为</span>
						<span lang="EN-US">Blogger</span>
						<span lang="ZH-CN">是无法知道自己的博客被多少人订阅和观看的，不同的客户端<wbr></wbr>，还有许多象</span>
						<span lang="EN-US">Bloglines</span>
						<span lang="ZH-CN">，</span>
						<span lang="EN-US">Gougou</span>
						<span lang="ZH-CN">这样的中转站，不同的标准，根本无法统计。</span>
				</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<div style="MARGIN-TOP: 0px; FONT-SIZE: 10pt; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle">
						<strong>4. 为什么没有给别人打分呢？</strong>
				</div>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">在公认的排名中，给别人打分，也有个信用度的问题<wbr></wbr>。象老白这样德高望重，品学兼优的人打出来的分数就可靠些<wbr></wbr>，小兄弟们打出来的分数就没有那么可靠。所以，在打分之前也涉及到
<script type="text/javascript"><![CDATA[lt;!--D(["mb","&lt;WBR&gt;一个权值或者信用度的问题。可是权重和信用度从什么地方来呢？&lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt; &lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt;&lt;span lang\u003d\"ZH-CN\"&gt;给文章打分而不是给人打分，这也比较复杂。博客&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;A&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;一月产&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;5&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;\n篇博客，篇篇都是精品，博客&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;B&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;一月产&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;10&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;篇，其中&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;3&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;篇是精品，&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;7&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;\n篇是他个人的八卦故事，谁的分数应该高一些？如果是按总分，显然&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;B&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;要高，但是&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;A&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;在常理判断上似乎更有价值一些，因为他精品多，阅读干扰却不多&lt;WBR&gt;。那我们就取平均值，问题又来了，&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;A&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;\n下个月只产&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;1&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;篇精品了，&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;B&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;还是&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;一月产&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;10&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;篇，&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;\n3&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;篇是精品，&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;7&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;篇非精品，哪个高？文章有太多的随机性和偶然性，而且因为文章数和&lt;WBR&gt;文章质量在不同的博客，不同的时间段是不一样的，给文章打分反而把&lt;WBR&gt;问题搞复杂了。&lt;/span&gt;&lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt; &lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt; &lt;/p&gt;\n&lt;p style\u003d\"margin-top:0px;font-size:10pt;margin-bottom:0px;vertical-align:middle\"&gt;&lt;strong&gt;5. 为什么没有搞客户端的评价体系？&lt;/strong&gt;&lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt; &lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt;&lt;span lang\u003d\"ZH-CN\"&gt;原因就是客户端太多，如果希望统一太复杂。在这点上&lt;WBR&gt;，我同意王建硕的说法，&lt;a href\u003d\"http://home.wangjianshuo.com/cn/20060327_ccieccaeecaee.htm\" target\u003d\"_blank\" onclick\u003d\"return top.js.OpenExtLink(window,event,this)\"&gt;当一件事情有赖于多于一个人的努力才能成功的话，他成功的可能性就&lt;WBR&gt;小很多\n&lt;/a&gt;。有条件的网站如&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;donews&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;，&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;gougou, feedsky&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;还是应该自己独立搞一个，或者小规模的联合一下，千万别等客户端的&lt;WBR&gt;统一。&lt;/span&gt;&lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt; &lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt;&lt;span lang\u003d\"ZH-CN\"&gt;等到一群博客大牛们把自己的&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Blogger Rank&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;",1]);//--&gt;]]&gt;</script><wbr></wbr>一个权值或者信用度的问题。可是权重和信用度从什么地方来呢？</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">
						<span lang="ZH-CN">给文章打分而不是给人打分，这也比较复杂。博客</span>
						<span lang="EN-US">A</span>
						<span lang="ZH-CN">一月产</span>
						<span lang="EN-US">5</span>
						<span lang="ZH-CN"> 篇博客，篇篇都是精品，博客</span>
						<span lang="EN-US">B</span>
						<span lang="ZH-CN">一月产</span>
						<span lang="EN-US">10</span>
						<span lang="ZH-CN">篇，其中</span>
						<span lang="EN-US">3</span>
						<span lang="ZH-CN">篇是精品，</span>
						<span lang="EN-US">7</span>
						<span lang="ZH-CN"> 篇是他个人的八卦故事，谁的分数应该高一些？如果是按总分，显然</span>
						<span lang="EN-US">B</span>
						<span lang="ZH-CN">要高，但是</span>
						<span lang="EN-US">A</span>
						<span lang="ZH-CN">在常理判断上似乎更有价值一些，因为他精品多，阅读干扰却不多<wbr></wbr>。那我们就取平均值，问题又来了，</span>
						<span lang="EN-US">A</span>
						<span lang="ZH-CN"> 下个月只产</span>
						<span lang="EN-US">1</span>
						<span lang="ZH-CN">篇精品了，</span>
						<span lang="EN-US">B</span>
						<span lang="ZH-CN">还是</span>
						<span lang="ZH-CN">一月产</span>
						<span lang="EN-US">10</span>
						<span lang="ZH-CN">篇，</span>
						<span lang="EN-US"> 3</span>
						<span lang="ZH-CN">篇是精品，</span>
						<span lang="EN-US">7</span>
						<span lang="ZH-CN">篇非精品，哪个高？文章有太多的随机性和偶然性，而且因为文章数和<wbr></wbr>文章质量在不同的博客，不同的时间段是不一样的，给文章打分反而把<wbr></wbr>问题搞复杂了。</span>
				</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">
						<span lang="ZH-CN">
						</span> </p>
				<p style="MARGIN-TOP: 0px; FONT-SIZE: 10pt; MARGIN-BOTTOM: 0px; VERTICAL-ALIGN: middle">
						<strong>5. 为什么没有搞客户端的评价体系？</strong>
				</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">
				</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">
						<span lang="ZH-CN">原因就是客户端太多，如果希望统一太复杂。在这点上<wbr></wbr>，我同意王建硕的说法，<a onclick="return top.js.OpenExtLink(window,event,this)" href="http://home.wangjianshuo.com/cn/20060327_ccieccaeecaee.htm" target="_blank">当一件事情有赖于多于一个人的努力才能成功的话，他成功的可能性就<wbr></wbr>小很多 </a>。有条件的网站如</span>
						<span lang="EN-US">donews</span>
						<span lang="ZH-CN">，</span>
						<span lang="EN-US">gougou, feedsky</span>
						<span lang="ZH-CN">还是应该自己独立搞一个，或者小规模的联合一下，千万别等客户端的<wbr></wbr>统一。</span>
				</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in"> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in">
						<span lang="ZH-CN">等到一群博客大牛们把自己的</span>
						<span lang="EN-US">Blogger Rank</span>
						<span lang="ZH-CN">
								<script type="text/javascript"><![CDATA[lt;!--D(["mb","图标象蓝色的&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Bloglines&lt;/span&gt;\n&lt;span lang\u003d\"ZH-CN\"&gt;订阅数，绿色的&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Gougou&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;订阅数一样挂在自己的博客上，大家又象讨论&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Alexa&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;排名一样为这个&lt;/span&gt;&lt;span lang\u003d\"EN-US\"&gt;Blogger Rank&lt;/span&gt;&lt;span lang\u003d\"ZH-CN\"&gt;\n争论不休。这个时候，才算略有小成。&lt;/span&gt;&lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in;font-family:SimSun\"&gt; &lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in;font-family:SimSun\"&gt; &lt;/p&gt;\n&lt;p style\u003d\"font-size:10pt;margin:0in\"&gt;正因为考虑到这些东西，才写下了&lt;a href\u003d\"http://blog.donews.com/henryhwa/archive/2006/03/09/759647.aspx\" target\u003d\"_blank\" onclick\u003d\"return top.js.OpenExtLink(window,event,this)\"&gt;这篇文章&lt;/a&gt;，就当作是抛砖引玉吧，希望看到更多更好的思路。&lt;/p&gt;\n&lt;/div&gt;",0]);D(["ce"]);//--&gt;]]&gt;</script>
 图标象蓝色的</span>
						<span lang="EN-US">Bloglines</span>
						<span lang="ZH-CN">订阅数，绿色的</span>
						<span lang="EN-US">Gougou</span>
						<span lang="ZH-CN">订阅数一样挂在自己的博客上，大家又象讨论</span>
						<span lang="EN-US">Alexa</span>
						<span lang="ZH-CN">排名一样为这个</span>
						<span lang="EN-US">Blogger Rank</span>
						<span lang="ZH-CN"> 争论不休。这个时候，才算略有小成。</span>
				</p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: SimSun"> </p>
				<p style="FONT-SIZE: 10pt; MARGIN: 0in; FONT-FAMILY: SimSun">正因为考虑到这些东西，才写下了<a onclick="return top.js.OpenExtLink(window,event,this)" href="http://blog.donews.com/henryhwa/archive/2006/03/09/759647.aspx" target="_blank">这篇文章</a>，就当作是抛砖引玉吧，希望看到更多更好的思路。<br /><br />from: <a href="http://blog.donews.com/henryhwa/archive/2006/03/29/798355.aspx">http://blog.donews.com/henryhwa/archive/2006/03/29/798355.aspx</a></p>
		</div>
<img src ="http://www.blogjava.net/weidagang2046/aggbug/91368.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weidagang2046/" target="_blank">weidagang2046</a> 2007-01-02 13:47 <a href="http://www.blogjava.net/weidagang2046/articles/91368.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Google SiteMap Protocol协议 </title><link>http://www.blogjava.net/weidagang2046/articles/91036.html</link><dc:creator>weidagang2046</dc:creator><author>weidagang2046</author><pubDate>Sat, 30 Dec 2006 09:36:00 GMT</pubDate><guid>http://www.blogjava.net/weidagang2046/articles/91036.html</guid><wfw:comment>http://www.blogjava.net/weidagang2046/comments/91036.html</wfw:comment><comments>http://www.blogjava.net/weidagang2046/articles/91036.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weidagang2046/comments/commentRss/91036.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weidagang2046/services/trackbacks/91036.html</trackback:ping><description><![CDATA[
		<div class="postText">在新浪看到这样的新闻<a href="http://tech.sina.com.cn/i/2006-11-17/11041242984.shtml">Google雅虎微软联手支持网页手工提交标准</a>, <font face="Arial">Google、微软和雅虎认为，统一标准有助于从整体上改进站点地图，从而搜索引擎可以将更广泛的信息加入索引。当然，搜索终端用户也将从中获益。Google网站管理员中心产品经理瓦内萨·福克斯(Vanessa Fox)表示：“我们的首要任务是为用户提供最佳搜索结果，以及为网站所有者运营网站提供便利。”Google、微软和雅虎还将推动其它搜索引擎运营商，以及相关软件厂商加入Sitemaps协议支持者的行列。<font face="Times New Roman">Google、雅虎以及微软宣布已经达成共识，旗下的搜索引擎将采用统一的Sitemaps 0.9(站点地图)协议对网站进行索引。目前，在</font><a class="akey" href="http://www.sitemaps.org/" target="_blank"><font face="Times New Roman">www.sitemaps.org</font></a></font><font face="Times New Roman">网站上，已经为网站管理员准备了一套简单快捷的指引，使搜索引擎能够完整、有效地对网站进行索引。了解一下Google SiteMap Protocol.<br /><br /></font></div>
		<p class="postText" style="TEXT-INDENT: 2em">Google SiteMap Protocol是Google自己推出的一种站点地图协议，此协议文件基于早期的robots.txt文件协议，并有所升级。在Google官方指南中指出加入了Google SiteMap文件的网站将更有利于Google网页爬行机器人的爬行索引，这样将提高索引网站内容的效率和准确度。文件协议应用了简单的XML格式，一共用到6个标签，其中关键标签包括链接地址、更新时间、更新频率和索引优先权。</p>
		<div class="postText">Google SiteMap文件生成后格式如下： </div>
		<xmp class="postText">
				<urlset xmlns="http://www.google.com/schemas/sitemap&#xD;&#xA;/0.84">
						<url>
								<loc>http://www.keyusoft.cn</loc>
								<lastmod>2005-06-03T04:20-08:00</lastmod>
								<changefreq>always</changefreq>
								<priority>1.0</priority>
						</url>
						<url>
								<loc>http://www.keyusoft.cn/post/140.html</loc>
								<lastmod>2005-06-02T20:20:36Z</lastmod>
								<changefreq>daily</changefreq>
								<priority>0.8</priority>
						</url>
				</urlset>
		</xmp>
		<div class="postText">XML标签 </div>
		<div class="postText">
				<ul>
						<li>changefreq:页面内容更新频率。 
</li>
						<li>lastmod:页面最后修改时间 
</li>
						<li>loc:页面永久链接地址 
</li>
						<li>priority:相对于其他页面的优先权 
</li>
						<li>url:相对于前4个标签的父标签 
</li>
						<li>urlset:相对于前5个标签的父标签 </li>
				</ul>
		</div>我将一句一句分解讲解这个xml文件的每一个标签： 
<ol><li>&lt;urlset xmlns="http://www.google.com/schemas/sitemap/0.84"&gt;<br />这一行定义了此xml文件的命名空间，相当于网页文件中的&lt;html&gt;标签一样的作用。 
</li><li><xmp><url></url></xmp>这是具体某一个链接的定义入口，你所希望展示在SiteMap文件中的每一个链接都要用&lt;url&gt;和&lt;/url&gt;包含在里面，这是必须的。 
</li><li><xmp><loc>http://www.keyusoft.cn</loc></xmp>用&lt;loc&gt;描述出具体的链接地址，这里需要注意的是链接地址中的一些特殊字符必须转换为XML(HTML)定义的转义字符，如下表： 
<table cellspacing="0" cellpadding="2" border="1"><tbody><tr><th colspan="2" rowspan="2">字符</th><th colspan="2">转义后的字符</th></tr><tr><th>HTML字符</th><th>字符编码</th></tr><tr><td nowrap="" width="125">and(和)</td><td width="125">&amp;</td><td width="75">&amp;amp;</td><td width="75">&amp;#38;</td></tr><tr><td nowrap="" width="125">单引号</td><td width="125">&amp;apos;</td><td width="75">&amp;apos;</td><td width="75">&amp;#39;</td></tr><tr><td nowrap="" width="125">双引号</td><td width="125">"</td><td width="75">&amp;quot;</td><td width="75">&amp;#34;</td></tr><tr><td nowrap="" width="125">大于号</td><td width="125">&gt;</td><td width="75">&amp;gt;</td><td width="75">&amp;#62;</td></tr><tr><td nowrap="" width="125">小于号</td><td width="125">&lt;</td><td width="75">&amp;lt;</td><td width="75">&amp;#60;</td></tr></tbody></table></li><li><xmp><lastmod>2005-06-03T04:20:32-08:00</lastmod></xmp>&lt;lastmod&gt;是用来指定该链接的最后更新时间，这个很重要。Google的机器人会在索引此链接前先和上次索引记录的最后更新时间进行比较，如果时间一样就会跳过不再索引。所以如果你的链接内容基于上次Google索引时的内容有所改变，应该更新该时间，让Google下次索引时会重新对该链接内容进行分析和提取关键字。这里必须用<a title="ISO 8601时间格式详细说明" href="http://www.w3.org/TR/NOTE-datetime">ISO 8601</a>中指定的时间格式进行描述，格式化的时间格式如下： 
<ul style="LIST-STYLE-TYPE: disc"><li>年：YYYY(2005) 
</li><li>年和月：YYYY-MM(2005-06) 
</li><li>年月日：YYYY-MM-DD(2005-06-04) 
</li><li>年月日小时分钟：YYYY-MM-DDThh:mmTZD(2005-06-04T10:37+08:00) 
</li><li>年月日小时分钟秒：YYYY-MM-DDThh:mmTZD(2005-06-04T10:37:30+08:00) </li></ul>这里需注意的是TZD，TZD指定就是本地时间区域标记，像中国就是+08:00了 
</li><li><xmp><changefreq>always</changefreq></xmp>用这个标签告诉Google此链接可能会出现的更新频率，比如首页肯定就要用always(经常)，而对于很久前的链接或者不再更新内容的链接就可以用yearly(每年)。这里可以用来描述的单词共这几个："always", "hourly", "daily", "weekly", "monthly", "yearly"，具体含义我就不用解释了吧，光看单词的意思就明白了。 
</li><li><xmp><priority>1.0</priority></xmp>&lt;priority&gt;是用来指定此链接相对于其他链接的优先权比值，此值定于0.0 - 1.0之间 
</li><li>还有&lt;/url&gt;和&lt;/urlset&gt;，这两个就是来关闭xml标签的，这和HTML中的&lt;/body&gt;和&lt;/html&gt;是一个道理 
</li><li><b>另外需要注意的是</b>，这个xml文件必须是utf-8的编码格式，不管你是手动生成还是通过代码生成，建议最好检查一下xml文件是否是utf-8编码，最简单的方法就是用记事本打开xml然后另存为时选择编码(或转换器)为UTF-8。 </li></ol><p>from: <a href="http://www.cnblogs.com/shanyou/archive/2006/11/17/564152.aspx">http://www.cnblogs.com/shanyou/archive/2006/11/17/564152.aspx</a></p><img src ="http://www.blogjava.net/weidagang2046/aggbug/91036.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weidagang2046/" target="_blank">weidagang2046</a> 2006-12-30 17:36 <a href="http://www.blogjava.net/weidagang2046/articles/91036.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Anti-Crawler Script</title><link>http://www.blogjava.net/weidagang2046/articles/88643.html</link><dc:creator>weidagang2046</dc:creator><author>weidagang2046</author><pubDate>Mon, 18 Dec 2006 13:42:00 GMT</pubDate><guid>http://www.blogjava.net/weidagang2046/articles/88643.html</guid><wfw:comment>http://www.blogjava.net/weidagang2046/comments/88643.html</wfw:comment><comments>http://www.blogjava.net/weidagang2046/articles/88643.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weidagang2046/comments/commentRss/88643.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weidagang2046/services/trackbacks/88643.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: DescriptionAn ASP script which can be adapted to keep specific crawlers (robots/spiders) out of your ASP-based website, or you can apply the rules to single a page. The latest version of the script al...&nbsp;&nbsp;<a href='http://www.blogjava.net/weidagang2046/articles/88643.html'>阅读全文</a><img src ="http://www.blogjava.net/weidagang2046/aggbug/88643.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weidagang2046/" target="_blank">weidagang2046</a> 2006-12-18 21:42 <a href="http://www.blogjava.net/weidagang2046/articles/88643.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在应用中加入全文检索功能——基于Java的全文索引引擎Lucene简介</title><link>http://www.blogjava.net/weidagang2046/articles/87684.html</link><dc:creator>weidagang2046</dc:creator><author>weidagang2046</author><pubDate>Thu, 14 Dec 2006 05:05:00 GMT</pubDate><guid>http://www.blogjava.net/weidagang2046/articles/87684.html</guid><wfw:comment>http://www.blogjava.net/weidagang2046/comments/87684.html</wfw:comment><comments>http://www.blogjava.net/weidagang2046/articles/87684.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weidagang2046/comments/commentRss/87684.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weidagang2046/services/trackbacks/87684.html</trackback:ping><description><![CDATA[
		<p>作者： 车东 Email: chedongATbigfoot.com/chedongATchedong.com</p>
		<p>写于：2002/08 最后更新：
<script language="Javascript" src="http://www.chedong.com/referer.js"></script>
 11/29/2006 17:23:30<br /><a href="http://www.chedong.com/tech/comments.php">Feed Back &gt;&gt;</a> (<a href="http://www.linuxforum.net/doc/smartq-grand.html">Read this before you ask question</a>)<a href="http://creativecommons.org/licenses/by-sa/2.5/"><br /><img alt="Creative Commons License" src="http://www.creativecommons.cn/images/public/somerights.gif" border="0" /></a>&lt;广告&gt;</p>
		<p>版权声明：可以任意转载，转载时请务必以超链接形式标明文章原始出处和作者信息及本声明<br /><a href="http://www.chedong.com/tech/lucene.html">http://www.chedong.com/tech/lucene.html</a></p>
		<p>关键词：Lucene java full-text search engine Chinese word segment</p>
		<p>
				<span style="FONT-WEIGHT: bold">
				</span>内容摘要：</p>
		<p>Lucene是一个基于Java的全文索引工具包。</p>
		<ol>
				<li>
						<a href="http://www.chedong.com/tech/lucene.html#intro">基于Java的全文索引引擎Lucene简介：关于作者和Lucene的历史</a>
				</li>
				<li>
						<a href="http://www.chedong.com/tech/lucene.html#compare">全文检索的实现：Luene全文索引和数据库索引的比较</a>
				</li>
				<li>
						<a href="http://www.chedong.com/tech/lucene.html#segment">中文切分词机制简介：基于词库和自动切分词算法的比较</a>
				</li>
				<li>
						<a href="http://www.chedong.com/tech/lucene.html#demo">具体的安装和使用简介：系统结构介绍和演示</a>
				</li>
				<li>
						<a href="http://www.chedong.com/tech/lucene.html#hacking">Hacking Lucene：简化的查询分析器，删除的实现，定制的排序，应用接口的扩展</a>
				</li>
				<li>
						<a href="http://www.chedong.com/tech/lucene.html#learn">从Lucene我们还可以学到什么</a>
				</li>
		</ol>
		<p>
				<a name="intro">
						<b>基于Java的全文索引/检索引擎——Lucene</b>
				</a>
		</p>
		<p>Lucene不是一个完整的全文索引应用，而是是一个用Java写的全文索引引擎工具包，它可以方便的嵌入到各种应用中实现针对应用的全文索引/检索功能。</p>
		<p>Lucene的作者：Lucene的贡献者<a href="http://www.nutch.org/blog/cutting.html">Doug Cutting</a>是一位资深全文索引/检索专家，曾经是V-Twin搜索引擎(Apple的Copland操作系统的成就之一)的主要开发者，后在Excite担任高级系统架构设计师，目前从事于一些INTERNET底层架构的研究。他贡献出的Lucene的目标是为各种中小型应用程序加入全文检索功能。</p>
		<p>Lucene的发展历程：早先发布在作者自己的<a href="http://www.lucene.com/">www.lucene.com</a>，后来发布在<a href="http://sourceforge.net/projects/lucene/">SourceForge</a>，2001年年底成为APACHE基金会jakarta的一个子项目：<a href="http://jakarta.apache.org/lucene/">http://jakarta.apache.org/lucene/</a></p>
		<p>已经有很多Java项目都使用了Lucene作为其后台的全文索引引擎，比较著名的有：</p>
		<ul>
				<li>
						<a href="http://www.jivesoftware.com/">J</a>
						<a href="http://www.jivesoftware.com/">ive</a>：WEB论坛系统； 
</li>
				<li>
						<a href="http://eyebrowse.tigris.org/">Eyebrows</a>：邮件列表HTML归档/浏览/查询系统，本文的主要参考文档“<a href="http://www.javaworld.com/javaworld/jw-09-2000/jw-0915-lucene_p.html">TheLucene search engine: Powerful, flexible, and free</a>”作者就是EyeBrows系统的主要开发者之一，而EyeBrows已经成为目前APACHE项目的主要邮件列表归档系统。 
</li>
				<li>
						<a href="http://xml.apache.org/cocoon/index.html">Cocoon</a>:基于XML的web发布框架，全文检索部分使用了Lucene 
</li>
				<li>
						<p align="left">
								<a href="http://www.eclipse.org/">Eclipse</a>:基于Java的开放开发平台，帮助部分的全文索引使用了Lucene</p>
				</li>
		</ul>
		<p>对于中文用户来说，最关心的问题是其是否支持中文的全文检索。但通过后面对于Lucene的结构的介绍，你会了解到由于Lucene良好架构设计，对中文的支持只需对其语言词法分析接口进行扩展就能实现对中文检索的支持。</p>
		<p>
				<b>
						<a name="compare">全文检索的实现机制</a>
				</b>
		</p>
		<p>Lucene的API接口设计的比较通用，输入输出结构都很像数据库的表==&gt;记录==&gt;字段，所以很多传统的应用的文件、数据库等都可以比较方便的映射到Lucene的存储结构/接口中。总体上看：可以先把<b>Lucene当成一个支持全文索引的数据库系统</b>。</p>
		<p>比较一下Lucene和数据库：</p>
		<table width="100%" border="1">
				<tbody>
						<tr>
								<td align="middle" width="50%">Lucene</td>
								<td align="middle" width="50%">数据库</td>
						</tr>
						<tr>
								<td width="50%">
										<pre>索引数据源：doc(field1,field2...) doc(field1,field2...)<br />                  \  indexer /<br />                 _____________<br />                | Lucene Index|<br />                --------------<br />                 / searcher \<br /> 结果输出：Hits(doc(field1,field2) doc(field1...))</pre>
								</td>
								<td width="50%">
										<pre> 索引数据源：record(field1,field2...) record(field1..)<br />              \  SQL: insert/<br />               _____________<br />              | DB  Index   |<br />               -------------<br />              / SQL: select \<br />结果输出：results(record(field1,field2..) record(field1...))</pre>
								</td>
						</tr>
						<tr>
								<td width="50%">Document：一个需要进行索引的“单元”<br />一个Document由多个字段组成</td>
								<td width="50%">Record：记录，包含多个字段</td>
						</tr>
						<tr>
								<td width="50%">Field：字段</td>
								<td width="50%">Field：字段</td>
						</tr>
						<tr>
								<td width="50%">Hits：查询结果集，由匹配的Document组成</td>
								<td width="50%">RecordSet：查询结果集，由多个Record组成</td>
						</tr>
				</tbody>
		</table>
		<p>
				<b>全文检索 ≠ like "%keyword%"</b>
		</p>
		<p>通常比较厚的书籍后面常常附关键词索引表（比如：北京：12, 34页，上海：3,77页……），它能够帮助读者比较快地找到相关内容的页码。而数据库索引能够大大提高查询的速度原理也是一样，想像一下通过书后面的索引查找的速度要比一页一页地翻内容高多少倍……而索引之所以效率高，另外一个原因是它是排好序的。<b>对于检索系统来说核心是一个排序问题</b>。</p>
		<p align="left">由于数据库索引不是为全文索引设计的，因此，<b>使用like "%keyword%"时，数据库索引是不起作用的</b>，在使用like查询时，搜索过程又变成类似于一页页翻书的遍历过程了，所以对于含有模糊查询的数据库服务来说，LIKE对性能的危害是极大的。如果是需要对多个关键词进行模糊匹配：like"%keyword1%" and like "%keyword2%" ...其效率也就可想而知了。</p>
		<p>所以建立一个高效检索系统的关键是建立一个类似于科技索引一样的反向索引机制，将数据源（比如多篇文章）排序顺序存储的同时，有另外一个排好序的关键词列表，用于存储关键词==&gt;文章映射关系，利用这样的映射关系索引：[关键词==&gt;出现关键词的文章编号，出现次数（甚至包括位置：起始偏移量，结束偏移量），出现频率]，检索过程就是把<b>模糊查询变成多个可以利用索引的精确查询的逻辑组合的过程</b>。从而大大提高了多关键词查询的效率，所以，全文检索问题归结到最后是一个排序问题。</p>
		<p>由此可以看出模糊查询相对数据库的精确查询是一个非常不确定的问题，这也是大部分数据库对全文检索支持有限的原因。Lucene最核心的特征是通过特殊的索引结构实现了传统数据库不擅长的全文索引机制，并提供了扩展接口，以方便针对不同应用的定制。</p>
		<p>可以通过一下表格对比一下数据库的模糊查询：</p>
		<table height="283" width="100%" border="1">
				<tbody>
						<tr>
								<td align="middle" width="9%" height="16">　</td>
								<td align="middle" width="47%" height="16">Lucene全文索引引擎</td>
								<td align="middle" width="40%" height="16">数据库</td>
						</tr>
						<tr>
								<td width="9%" height="48">索引</td>
								<td width="47%" height="48">将数据源中的数据都通过全文索引一一建立反向索引</td>
								<td width="40%" height="48">对于LIKE查询来说，数据传统的索引是根本用不上的。数据需要逐个便利记录进行GREP式的模糊匹配，比有索引的搜索速度要有多个数量级的下降。</td>
						</tr>
						<tr>
								<td width="9%" height="49">匹配效果</td>
								<td width="47%" height="49">通过词元(term)进行匹配，通过语言分析接口的实现，可以实现对中文等非英语的支持。</td>
								<td width="40%" height="49">使用：like "%net%" 会把netherlands也匹配出来，<br />多个关键词的模糊匹配：使用like "%com%net%"：就不能匹配词序颠倒的xxx.net..xxx.com</td>
						</tr>
						<tr>
								<td width="9%" height="32">匹配度</td>
								<td width="47%" height="32">有匹配度算法，将匹配程度（相似度）比较高的结果排在前面。</td>
								<td width="40%" height="32">没有匹配程度的控制：比如有记录中net出现5词和出现1次的，结果是一样的。</td>
						</tr>
						<tr>
								<td width="9%" height="32">结果输出</td>
								<td width="47%" height="32">通过特别的算法，将最匹配度最高的头100条结果输出，结果集是缓冲式的小批量读取的。</td>
								<td width="40%" height="32">返回所有的结果集，在匹配条目非常多的时候（比如上万条）需要大量的内存存放这些临时结果集。</td>
						</tr>
						<tr>
								<td width="9%" height="32">可定制性</td>
								<td width="47%" height="32">通过不同的语言分析接口实现，可以方便的定制出符合应用需要的索引规则（包括对中文的支持）</td>
								<td width="40%" height="32">没有接口或接口复杂，无法定制</td>
						</tr>
						<tr>
								<td width="9%" height="32">结论</td>
								<td width="47%" height="32">高负载的模糊查询应用，需要负责的模糊查询的规则，索引的资料量比较大</td>
								<td width="40%" height="32">使用率低，模糊匹配规则简单或者需要模糊查询的资料量少</td>
						</tr>
				</tbody>
		</table>
		<p>
				<span style="FONT-WEIGHT: bold">全文检索和数据库应用最大的不同在于：让</span>
				<span style="FONT-WEIGHT: bold">最相关的</span>
				<span style="FONT-WEIGHT: bold">头100条结果满足98%以上用户的需求<br /></span>
				<br />Lucene的创新之处：</p>
		<p>大部分的搜索（数据库）引擎都是用B树结构来维护索引，索引的更新会导致大量的IO操作，Lucene在实现中，对此稍微有所改进：不是维护一个索引文件，而是在扩展索引的时候不断创建新的索引文件，然后定期的把这些新的小索引文件合并到原先的大索引中（针对不同的更新策略，批次的大小可以调整），这样在不影响检索的效率的前提下，提高了索引的效率。</p>
		<p>Lucene和其他一些全文检索系统/应用的比较：</p>
		<table width="100%" border="1">
				<tbody>
						<tr>
								<td align="middle" width="18%">　</td>
								<td align="middle" width="45%">Lucene</td>
								<td align="middle" width="37%">其他开源全文检索系统</td>
						</tr>
						<tr>
								<td width="18%">增量索引和批量索引</td>
								<td width="45%">可以进行增量的索引(Append)，可以对于大量数据进行批量索引，并且接口设计用于优化批量索引和小批量的增量索引。</td>
								<td width="37%">很多系统只支持批量的索引，有时数据源有一点增加也需要重建索引。</td>
						</tr>
						<tr>
								<td width="18%">数据源</td>
								<td width="45%">Lucene没有定义具体的数据源，而是一个文档的结构，因此可以非常灵活的适应各种应用（只要前端有合适的转换器把数据源转换成相应结构），</td>
								<td width="37%">很多系统只针对网页，缺乏其他格式文档的灵活性。</td>
						</tr>
						<tr>
								<td width="18%">索引内容抓取</td>
								<td width="45%">Lucene的文档是由多个字段组成的，甚至可以控制那些字段需要进行索引，那些字段不需要索引，近一步索引的字段也分为需要分词和不需要分词的类型：<br />   需要进行分词的索引，比如：标题，文章内容字段<br />   不需要进行分词的索引，比如：作者/日期字段</td>
								<td width="37%">缺乏通用性，往往将文档整个索引了</td>
						</tr>
						<tr>
								<td width="18%">语言分析</td>
								<td width="45%">通过语言分析器的不同扩展实现：<br />可以过滤掉不需要的词：an the of 等，<br />西文语法分析：将jumps jumped jumper都归结成jump进行索引/检索<br />非英文支持：对亚洲语言，阿拉伯语言的索引支持</td>
								<td width="37%">缺乏通用接口实现</td>
						</tr>
						<tr>
								<td width="18%">查询分析</td>
								<td width="45%">通过查询分析接口的实现，可以定制自己的查询语法规则：<br />比如： 多个关键词之间的 + - and or关系等</td>
								<td width="37%">　</td>
						</tr>
						<tr>
								<td width="18%">并发访问</td>
								<td width="45%">能够支持多用户的使用</td>
								<td width="37%">　</td>
						</tr>
				</tbody>
		</table>
		<p>　</p>
		<p>
				<b>
						<a name="segment">关于亚洲语言的的切分词问题(Word Segment)</a>
				</b>
		</p>
		<p>对于中文来说，全文索引首先还要解决一个语言分析的问题，对于英文来说，语句中单词之间是天然通过空格分开的，但亚洲语言的中日韩文语句中的字是一个字挨一个，所有，首先要把语句中按“词”进行索引的话，这个词如何切分出来就是一个很大的问题。</p>
		<p>首先，肯定不能用单个字符作(si-gram)为索引单元，否则查“上海”时，不能让含有“海上”也匹配。</p>
		<p>但一句话：“北京天安门”，计算机如何按照中文的语言习惯进行切分呢？<br />“北京 天安门” 还是“北 京 天安门”？让计算机能够按照语言习惯进行切分，往往需要机器有一个比较丰富的词库才能够比较准确的识别出语句中的单词。</p>
		<p>另外一个解决的办法是采用自动切分算法：将单词按照2元语法(bigram)方式切分出来，比如：<br />"北京天安门" ==&gt; "北京 京天 天安 安门"。</p>
		<p>这样，在查询的时候，无论是查询"北京" 还是查询"天安门"，将查询词组按同样的规则进行切分："北京"，"天安安门"，多个关键词之间按与"and"的关系组合，同样能够正确地映射到相应的索引中。这种方式对于其他亚洲语言：韩文，日文都是通用的。</p>
		<p>基于自动切分的最大优点是没有词表维护成本，实现简单，缺点是索引效率低，但对于中小型应用来说，基于2元语法的切分还是够用的。基于2元切分后的索引一般大小和源文件差不多，而对于英文，索引文件一般只有原文件的30%-40%不同，</p>
		<table height="68" width="100%" border="1">
				<tbody>
						<tr>
								<td align="middle" width="11%" height="18">
										<br />
								</td>
								<td align="middle" width="39%" height="18">自动切分</td>
								<td align="middle" width="50%" height="18">词表切分</td>
						</tr>
						<tr>
								<td width="11%" height="16">实现</td>
								<td width="39%" height="16">实现非常简单</td>
								<td width="50%" height="16">实现复杂</td>
						</tr>
						<tr>
								<td width="11%" height="16">查询</td>
								<td width="39%" height="16">增加了查询分析的复杂程度，</td>
								<td width="50%" height="16">适于实现比较复杂的查询语法规则</td>
						</tr>
						<tr>
								<td width="11%" height="16">存储效率</td>
								<td width="39%" height="16">索引冗余大，索引几乎和原文一样大</td>
								<td width="50%" height="16">索引效率高，为原文大小的30％左右</td>
						</tr>
						<tr>
								<td width="11%" height="16">维护成本</td>
								<td width="39%" height="16">无词表维护成本</td>
								<td width="50%" height="16">词表维护成本非常高：中日韩等语言需要分别维护。<br />还需要包括词频统计等内容</td>
						</tr>
						<tr>
								<td width="11%" height="16">适用领域</td>
								<td width="39%" height="16">嵌入式系统：运行环境资源有限<br />分布式系统：无词表同步问题<br />多语言环境：无词表维护成本</td>
								<td width="50%" height="16">对查询和存储效率要求高的专业搜索引擎<br /></td>
						</tr>
				</tbody>
		</table>
		<p>目前比较大的搜索引擎的语言分析算法一般是基于以上2个机制的结合。关于中文的语言分析算法，大家可以在Google查关键词"wordsegment search"能找到更多相关的资料。</p>
		<p>
				<a name="demo">
						<b>安装和使用</b>
				</a>
		</p>
		<p>下载：<a href="http://jakarta.apache.org/lucene/">http://jakarta.apache.org/lucene/</a></p>
		<p>注意：Lucene中的一些比较复杂的词法分析是用JavaCC生成的（JavaCC：JavaCompilerCompiler，纯Java的词法分析生成器），所以如果从源代码编译或需要修改其中的QueryParser、定制自己的词法分析器，还需要从<a href="https://javacc.dev.java.net/">https://javacc.dev.java.net/</a>下载javacc。</p>
		<p>lucene的组成结构：对于外部应用来说索引模块(index)和检索模块(search)是主要的外部应用入口</p>
		<table width="100%" border="1">
				<tbody>
						<tr>
								<td width="27%">org.apache.Lucene.search/</td>
								<td width="73%">搜索入口</td>
						</tr>
						<tr>
								<td width="27%">org.apache.Lucene.index/</td>
								<td width="73%">索引入口</td>
						</tr>
						<tr>
								<td width="27%">org.apache.Lucene.analysis/</td>
								<td width="73%">语言分析器</td>
						</tr>
						<tr>
								<td width="27%">org.apache.Lucene.queryParser/</td>
								<td width="73%">查询分析器</td>
						</tr>
						<tr>
								<td width="27%">org.apache.Lucene.document/</td>
								<td width="73%">存储结构</td>
						</tr>
						<tr>
								<td width="27%">org.apache.Lucene.store/ </td>
								<td width="73%">底层IO/存储结构</td>
						</tr>
						<tr>
								<td width="27%">org.apache.Lucene.util/</td>
								<td width="73%">一些公用的数据结构</td>
						</tr>
				</tbody>
		</table>
		<p>简单的例子演示一下Lucene的使用方法：</p>索引过程：从命令行读取文件名（多个），将文件分路径(path字段)和内容(body字段)2个字段进行存储，并对内容进行全文索引：索引的单位是Document对象，每个Document对象包含多个字段Field对象，针对不同的字段属性和数据输出的需求，对字段还可以选择不同的索引/存储字段规则，列表如下： 
<table border="1"><tbody><tr><th>方法</th><th>切词</th><th>索引</th><th>存储</th><th>用途</th></tr><tr><td>Field.Text(String name, String value)</td><td>Yes</td><td>Yes</td><td>Yes</td><td valign="top">切分词索引并存储，比如：标题，内容字段</td></tr><tr><td>Field.Text(String name, Reader value)</td><td>Yes</td><td>Yes</td><td>No</td><td valign="top">切分词索引不存储，比如：META信息，<br />不用于返回显示，但需要进行检索内容</td></tr><tr><td>Field.Keyword(String name, String value)</td><td>No</td><td>Yes</td><td>Yes</td><td valign="top">不切分索引并存储，比如：日期字段</td></tr><tr><td>Field.UnIndexed(String name, String value)</td><td>No</td><td>No</td><td>Yes</td><td valign="top">不索引，只存储，比如：文件路径</td></tr><tr><td>Field.UnStored(String name, String value)</td><td>Yes</td><td>Yes</td><td>No</td><td valign="top">只全文索引，不存储</td></tr></tbody></table><pre>public class IndexFiles { <br />  //使用方法：: IndexFiles [索引输出目录] [索引的文件列表] ... <br />  public static void main(String[] args) throws Exception {<br />    String indexPath = args[0];<br />    IndexWriter writer;<br />    //用指定的语言分析器构造一个新的写索引器（第3个参数表示是否为追加索引）<br />    writer = new IndexWriter(indexPath, new SimpleAnalyzer(), false);<br /><br />    for (int i=1; i&lt;args.length; i++) {<br />      System.out.println("Indexing file " + args[i]);<br />      InputStream is = new FileInputStream(args[i]);<br /><br />      //构造包含2个字段Field的Document对象<br />      //一个是路径path字段，不索引，只存储<br />      //一个是内容body字段，进行全文索引，并存储<br />      Document doc = new Document();<br />      doc.add(Field.UnIndexed("path", args[i]));<br />      doc.add(Field.Text("body", (Reader) new InputStreamReader(is)));<br />      //将文档写入索引<br />      writer.addDocument(doc);<br />      is.close();<br />    };<br />    //关闭写索引器<br />    writer.close();<br />  }<br />}<br />　</pre><p>索引过程中可以看到：</p><ul><li>语言分析器提供了抽象的接口，因此语言分析(Analyser)是可以定制的，虽然lucene缺省提供了2个比较通用的分析器SimpleAnalyser和StandardAnalyser，这2个分析器缺省都不支持中文，所以要加入对中文语言的切分规则，需要修改这2个分析器。 
</li><li>Lucene并没有规定数据源的格式，而只提供了一个通用的结构（Document对象）来接受索引的输入，因此输入的数据源可以是：数据库，WORD文档，PDF文档，HTML文档……只要能够设计相应的解析转换器将数据源构造成成Docuement对象即可进行索引。 
</li><li>对于大批量的数据索引，还可以通过调整IndexerWrite的文件合并频率属性（mergeFactor）来提高批量索引的效率。 </li></ul><p>检索过程和结果显示：</p><p>搜索结果返回的是Hits对象，可以通过它再访问Document==&gt;Field中的内容。</p><p>假设根据body字段进行全文检索，可以将查询结果的path字段和相应查询的匹配度(score)打印出来，</p><pre>public class Search { <br />  public static void main(String[] args) throws Exception {<br />    String indexPath = args[0], queryString = args[1];<br />    //指向索引目录的搜索器<br />    Searcher searcher = new IndexSearcher(indexPath);<br />    //查询解析器：使用和索引同样的语言分析器<br />    Query query = QueryParser.parse(queryString, "body", <br />                              new SimpleAnalyzer());<br />    //搜索结果使用Hits存储<br />    Hits hits = searcher.search(query);<br />    //通过hits可以访问到相应字段的数据和查询的匹配度<br />    for (int i=0; i&lt;hits.length(); i++) {<br />      System.out.println(hits.doc(i).get("path") + "; Score: " + <br />                         hits.score(i));<br />    };<br />  }<br />}</pre>在整个检索过程中，语言分析器，查询分析器，甚至搜索器（Searcher）都是提供了抽象的接口，可以根据需要进行定制。 
<p><b><a name="hacking">Hacking Lucene</a></b></p><p><b>简化的查询分析器</b></p><p>个人感觉lucene成为JAKARTA项目后，画在了太多的时间用于调试日趋复杂QueryParser，而其中大部分是大多数用户并不很熟悉的，目前LUCENE支持的语法：</p><p>Query ::= ( Clause )*<br />Clause ::= ["+", "-"] [&lt;TERM&gt; ":"] ( &lt;TERM&gt; | "(" Query ")")</p><p>中间的逻辑包括：and or + - &amp;&amp;||等符号，而且还有"短语查询"和针对西文的前缀/模糊查询等，个人感觉对于一般应用来说，这些功能有一些华而不实，其实能够实现目前类似于Google的查询语句分析功能其实对于大多数用户来说已经够了。所以，Lucene早期版本的QueryParser仍是比较好的选择。</p><p><b>添加修改删除指定记录（Document）</b></p><p>Lucene提供了索引的扩展机制，因此索引的动态扩展应该是没有问题的，而指定记录的修改也似乎只能通过记录的删除，然后重新加入实现。如何删除指定的记录呢？删除的方法也很简单，只是需要在索引时根据数据源中的记录ID专门另建索引，然后利用IndexReader.delete(Termterm)方法通过这个记录ID删除相应的Document。</p><p><b>根据某个字段值的排序功能</b></p><p>lucene缺省是按照自己的相关度算法（score）进行结果排序的，但能够根据其他字段进行结果排序是一个在LUCENE的开发邮件列表中经常提到的问题，很多原先基于数据库应用都需要除了基于匹配度（score）以外的排序功能。而从全文检索的原理我们可以了解到，任何不基于索引的搜索过程效率都会导致效率非常的低，如果基于其他字段的排序需要在搜索过程中访问存储字段，速度回大大降低，因此非常是不可取的。</p><p>但这里也有一个折中的解决方法：在搜索过程中能够影响排序结果的只有索引中已经存储的docID和score这2个参数，所以，基于score以外的排序，其实可以通过将数据源预先排好序，然后根据docID进行排序来实现。这样就避免了在LUCENE搜索结果外对结果再次进行排序和在搜索过程中访问不在索引中的某个字段值。</p><p>这里需要修改的是IndexSearcher中的HitCollector过程：</p><pre>...<br />　scorer.score(new HitCollector() {<br />	private float minScore = 0.0f;<br />	public final void collect(int doc, float score) {<br />	  if (score &gt; 0.0f &amp;&amp;			  // ignore zeroed buckets<br />	      (bits==null || bits.get(doc))) {	  // skip docs not in bits<br />	    totalHits[0]++;<br />	    if (score &gt;= minScore) {<br />              /* 原先：Lucene将docID和相应的匹配度score例入结果命中列表中：<br />	       * hq.put(new ScoreDoc(doc, score));	  // update hit queue<br />               * 如果用doc 或 1/doc 代替 score，就实现了根据docID顺排或逆排<br />               * 假设数据源索引时已经按照某个字段排好了序，而结果根据docID排序也就实现了<br />               * 针对某个字段的排序，甚至可以实现更复杂的score和docID的拟合。<br />               */<br />              hq.put(new ScoreDoc(doc, (float) 1/doc )); <br />	      if (hq.size() &gt; nDocs) {		  // if hit queue overfull<br />		hq.pop();			  // remove lowest in hit queue<br />		minScore = ((ScoreDoc)hq.top()).score; // reset minScore<br />	      }<br />	    }<br />	  }<br />	}<br />      }, reader.maxDoc());</pre><p><b>更通用的输入输出接口</b></p><p>虽然lucene没有定义一个确定的输入文档格式，但越来越多的人想到使用一个标准的中间格式作为Lucene的数据导入接口，然后其他数据，比如PDF只需要通过解析器转换成标准的中间格式就可以进行数据索引了。这个中间格式主要以XML为主，类似实现已经不下4，5个：</p><pre>数据源: WORD       PDF     HTML    DB       other<br />         \          |       |      |         /<br />                       XML中间格式<br />                            |<br />                     Lucene INDEX</pre><p>目前还没有针对MSWord文档的解析器，因为Word文档和基于ASCII的RTF文档不同，需要使用COM对象机制解析。这个是我在Google上查的相关资料：<a href="http://www.intrinsyc.com/products/enterprise_applications.asp">http://www.intrinsyc.com/products/enterprise_applications.asp</a><br />另外一个办法就是把Word文档转换成text：<a href="http://www.winfield.demon.nl/index.html">http://www.winfield.demon.nl/index.html</a><br /></p><p><br /><b>索引过程优化</b></p><p>索引一般分2种情况，一种是小批量的索引扩展，一种是大批量的索引重建。在索引过程中，并不是每次新的DOC加入进去索引都重新进行一次索引文件的写入操作（文件I/O是一件非常消耗资源的事情）。</p><p>Lucene先在内存中进行索引操作，并根据一定的批量进行文件的写入。这个批次的间隔越大，文件的写入次数越少，但占用内存会很多。反之占用内存少，但文件IO操作频繁，索引速度会很慢。在IndexWriter中有一个MERGE_FACTOR参数可以帮助你在构造索引器后根据应用环境的情况充分利用内存减少文件的操作。根据我的使用经验：缺省Indexer是每20条记录索引后写入一次，每将MERGE_FACTOR增加50倍，索引速度可以提高1倍左右。<br /></p><p><span style="FONT-WEIGHT: bold">搜索过程优化<br /></span></p><p><span style="FONT-WEIGHT: bold"></span>lucene支持内存索引：这样的搜索比基于文件的I/O有数量级的速度提升。<br /><a href="http://www.onjava.com/lpt/a/3273">http://www.onjava.com/lpt/a/3273</a><br />而尽可能减少IndexSearcher的创建和对搜索结果的前台的缓存也是必要的。<br /><span style="FONT-WEIGHT: bold"></span></p><p><b></b></p><p>Lucene面向全文检索的优化在于首次索引检索后，并不把所有的记录（Document）具体内容读取出来，而起只将所有结果中匹配度最高的头100条结果（TopDocs）的ID放到结果集缓存中并返回，这里可以比较一下数据库检索：如果是一个10,000条的数据库检索结果集，数据库是一定要把所有记录内容都取得以后再开始返回给应用结果集的。所以即使检索匹配总数很多，Lucene的结果集占用的内存空间也不会很多。对于一般的模糊检索应用是用不到这么多的结果的，头100条已经可以满足90%以上的检索需求。<br /></p><p>如果首批缓存结果数用完后还要读取更后面的结果时Searcher会再次检索并生成一个上次的搜索缓存数大1倍的缓存，并再重新向后抓取。所以如果构造一个Searcher去查1－120条结果，Searcher其实是进行了2次搜索过程：头100条取完后，缓存结果用完，Searcher重新检索再构造一个200条的结果缓存，依此类推，400条缓存，800条缓存。由于每次Searcher对象消失后，这些缓存也访问那不到了，你有可能想将结果记录缓存下来，缓存数尽量保证在100以下以充分利用首次的结果缓存，不让Lucene浪费多次检索，而且可以分级进行结果缓存。<br /></p><p>Lucene的另外一个特点是在收集结果的过程中将匹配度低的结果自动过滤掉了。这也是和数据库应用需要将搜索的结果全部返回不同之处。</p><p><a href="http://sourceforge.net/projects/weblucene/">我的一些尝试</a>：</p><ul><li>支持中文的Tokenizer：这里有2个版本，一个是通过JavaCC生成的，对CJK部分按一个字符一个TOKEN索引，另外一个是从SimpleTokenizer改写的，对英文支持数字和字母TOKEN，对中文按迭代索引。 
</li><li>基于XML数据源的索引器：XMLIndexer，因此所有数据源只要能够按照DTD转换成指定的XML，就可以用XMLIndxer进行索引了。 
</li><li>根据某个字段排序：按记录索引顺序排序结果的搜索器：IndexOrderSearcher，因此如果需要让搜索结果根据某个字段排序，可以让数据源先按某个字段排好序（比如：PriceField），这样索引后，然后在利用这个按记录的ID顺序检索的搜索器，结果就是相当于是那个字段排序的结果了。 </li></ul><p><a name="learn"><b>从Lucene学到更多</b></a></p><p>Luene的确是一个面对对象设计的典范</p><ul><li>所有的问题都通过一个额外抽象层来方便以后的扩展和重用：你可以通过重新实现来达到自己的目的，而对其他模块而不需要； 
</li><li>简单的应用入口Searcher, Indexer，并调用底层一系列组件协同的完成搜索任务； 
</li><li>所有的对象的任务都非常专一：比如搜索过程：QueryParser分析将查询语句转换成一系列的精确查询的组合(Query),通过底层的索引读取结构IndexReader进行索引的读取，并用相应的打分器给搜索结果进行打分/排序等。所有的功能模块原子化程度非常高，因此可以通过重新实现而不需要修改其他模块。  
</li><li>除了灵活的应用接口设计，Lucene还提供了一些适合大多数应用的语言分析器实现（SimpleAnalyser,StandardAnalyser），这也是新用户能够很快上手的重要原因之一。 </li></ul><p>这些优点都是非常值得在以后的开发中学习借鉴的。作为一个通用工具包，Lunece的确给予了需要将全文检索功能嵌入到应用中的开发者很多的便利。</p><p>此外，通过对Lucene的学习和使用，我也更深刻地理解了为什么很多数据库优化设计中要求，比如：</p><ul><li>尽可能对字段进行索引来提高查询速度，但过多的索引会对数据库表的更新操作变慢，而对结果过多的排序条件，实际上往往也是性能的杀手之一。 
</li><li>很多商业数据库对大批量的数据插入操作会提供一些优化参数，这个作用和索引器的merge_factor的作用是类似的， 
</li><li>20%/80%原则：查的结果多并不等于质量好，尤其对于返回结果集很大，如何优化这头几十条结果的质量往往才是最重要的。 
</li><li>尽可能让应用从数据库中获得比较小的结果集，因为即使对于大型数据库，对结果集的随机访问也是一个非常消耗资源的操作。<br /></li></ul><p>参考资料：</p><p>Apache: Lucene Project<br /><a href="http://jakarta.apache.org/lucene/">http://jakarta.apache.org/lucene/<br /></a>Lucene开发/用户邮件列表归档<br /><a href="http://www.mail-archive.com/lucene-dev@jakarta.apache.org/">Lucene-dev@jakarta.apache.org</a><br /><a href="http://www.mail-archive.com/lucene-user@jakarta.apache.org/">Lucene-user@jakarta.apache.org</a></p><p>The Lucene search engine: Powerful, flexible, and free<br /><a href="http://www.javaworld.com/javaworld/jw-09-2000/jw-0915-lucene_p.html">http://www.javaworld.com/javaworld/jw-09-2000/jw-0915-Lucene_p.html</a></p><p>Lucene Tutorial<br /><a href="http://www.darksleep.com/puff/lucene/lucene.html">http://www.darksleep.com/puff/lucene/lucene.html</a></p><p>Notes on distributed searching with Lucene<br /><a href="http://home.clara.net/markharwood/lucene/">http://home.clara.net/markharwood/lucene/</a></p><p>中文语言的切分词<br /><a href="http://www.google.com/search?sourceid=navclient&amp;hl=zh-CN&amp;q=chinese+word+segment">http://www.google.com/search?sourceid=navclient&amp;hl=zh-CN&amp;q=chinese+word+segment</a></p><p>搜索引擎工具介绍<a href="http://searchtools.com/"><br />http://searchtools.com/</a></p><p>Lucene作者Cutting的几篇论文和专利<br /><a href="http://lucene.sourceforge.net/publications.html">http://lucene.sourceforge.net/publications.html</a> </p><p>Lucene的.NET实现：dotLucene<br /><a href="http://sourceforge.net/projects/dotlucene/">http://sourceforge.net/projects/dotlucene/<br /></a></p><p>Lucene作者Cutting的另外一个项目：基于Java的搜索引擎Nutch<br /><a href="http://www.nutch.org/">http://www.nutch.org/</a>   <a href="http://sourceforge.net/projects/nutch/">http://sourceforge.net/projects/nutch/<br /></a></p><p>关于基于词表和N-Gram的切分词比较<br /><a href="http://china.nikkeibp.co.jp/cgi-bin/china/news/int/int200302100112.html">http://china.nikkeibp.co.jp/cgi-bin/china/news/int/int200302100112.html</a><br /><br />2005-01-08 <a href="http://lucene.sourceforge.net/talks/pisa/">Cutting在Pisa大学做的关于Lucene的讲座：非常详细的Lucene架构解说</a></p><p>特别感谢：<br /><a href="http://www.google.com/search?q=%22Jack+Xu%22+Excite">前网易CTO许良杰(Jack Xu)</a>给我的指导：是您将我带入了搜索引擎这个行业。</p>原文出处：&lt;ahref="http://www.chedong.com/tech/lucene.html"&gt;http://www.chedong.com/tech/lucene.html&lt;/a&gt;<br /><br />from: <img src ="http://www.blogjava.net/weidagang2046/aggbug/87684.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weidagang2046/" target="_blank">weidagang2046</a> 2006-12-14 13:05 <a href="http://www.blogjava.net/weidagang2046/articles/87684.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Similarity Flooding </title><link>http://www.blogjava.net/weidagang2046/articles/81825.html</link><dc:creator>weidagang2046</dc:creator><author>weidagang2046</author><pubDate>Fri, 17 Nov 2006 10:25:00 GMT</pubDate><guid>http://www.blogjava.net/weidagang2046/articles/81825.html</guid><wfw:comment>http://www.blogjava.net/weidagang2046/comments/81825.html</wfw:comment><comments>http://www.blogjava.net/weidagang2046/articles/81825.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weidagang2046/comments/commentRss/81825.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weidagang2046/services/trackbacks/81825.html</trackback:ping><description><![CDATA[
		<p>算法大致思路：<br />        把要匹配的模型转换为带标记的有向图（directed labeled graphs。由节点和弧组成的图，允许对象用自身的属性及其和其他对象的关系来定义，类似于ER图）。这些图要用来做迭代的不动点计算，计算结果将告诉我们一张图里的哪些节点和第二张图的节点相似。<br />        为了计算相似度，我们利用了这样一个直觉：两个不同的节点是相似的，当它们邻接元素是相似的。换句话说，两个元素相似性的一部分传播给了它们各自的邻居，这种传播方式类似于IP广播，这也是SF这个名字的由来。我们把算法的结果叫做一个 mapping，然后根据匹配目标，选择特定的过滤器来过滤出一个原始结果的子集。我们希望能够人工对结果进行修正，需要修正的成员数目就反映了算法的准确性。<br /><br />概述：<br /><br />        假设有2个schema，S1和S2。我们要为S1里每一个元素在S2中找到匹配的元素。<br />      过程如下：<br />      1. G1 = SQL2Graph(S1); G2 = SQL2Graph(S2);  把schema变成图，图采用了Open Information Model (OIM)规格，图中node采用矩形和卵形，矩形是文字描述，卵形是标识符<br /><br />      2. initialMap = StringMatch(G1, G2);      用字符串匹配做为初始匹配，主要是比较通常的前缀和后缀，这样的结果通常是不准确的<br /><br />      3. product = SFJoin(G1, G2, initialMap);      用SF算法生成结果。<font color="#0000ff">假设两个不同的节点是相似的，则它们邻接元素的相似度增加。经过一系列的迭代，这种相似度会传遍整个图<br /></font><br />      4. result = SelectThreshold(product);   结果筛选<br /><br /><br />SF算法<br /><br />      图中的每条边，用一个三元组表示（s，p，o），分别是 源点，边名，目的点。<br /><br /><img height="271" alt="δ2.JPG" src="http://www.cnblogs.com/images/cnblogs_com/anf/δ2.JPG" width="762" border="0" /><br />     <font color="#0000ff"> 相似度传播图：首先定义pairwise connectivity graph(PCG) ： ((x; y); p; (x'; y')) 属于 PCG(A;B)&lt;==&gt;(x; p; x') € A and (y; p; y') € B。 <font color="#ff0000">关键是p要相同，也就是边的名字一样。</font>式子从右向左推导，就可以A、B从两个模型建立起它们的PCG。</font>图中的每个节点，都是A和B中的元素构成的2元组，叫做map pairs。<br />      induced propagation graph。从PCG推导而来，加上了反向的边，边上注明了[传播系数]，值为 1/n，n为相应的边的数目。<br />      <font color="#0000ff">不动点计算：</font><br />            设ó(x; y) &gt; 0 代表了节点x € A 和 y € B 的相似度，是在整个 A X B的范围上定义的。我们把 ó 叫做 mapping。相似度的计算就是基于ó-values的迭代计算。设 ó<sup>i</sup> 代表了第 i 次迭代后的结果，ó<sup>0</sup> 是初始相似度（可以用字符串相似度的办法的得出，在我们的例子里，没有 ó<sup>0</sup> ，即让 ó<sup>0</sup> =1）。<br />            每次迭代中，ó-values 都会根据其邻居paris的 <font color="#008000">ó-values  乘以[传播系数]</font> 来增加。例如，在第一次迭代 ó<sup>1</sup>(a1; b1) = ó<sup>0</sup>(a1; b1) + ó<sup>0</sup>(a; b) * 0.5 = 1.5。类似的，ó<sup>1</sup>(a, b) = ó<sup>0</sup>(a, b) + ó<sup>0</sup>(a1; b1) * 1.0 + ó<sup>0</sup>(a2, b1) *1.0 = 3.0。接下来，所有 ó 值进行正规化，比如除以当前迭代的 ó<sup></sup>的最大值，保证所有 ó 都不大于1。所以在正规化以后，ó<sup>1</sup>(a; b) = 1.0, ó<sup>1</sup>(a1, b1) = 1.5/3.0 = 0.5。一般情况下，迭代如下进行：</p>
		<p>
				<img height="127" alt="未命名4.JPG" src="http://www.cnblogs.com/images/cnblogs_com/anf/未命名4.JPG" width="466" border="0" />
				<br />
				<br />
				<img height="1" src="http://www.cnblogs.com/WebResource.axd?d=pLXXeGbWF7eXU8SMs2-GFZvUWY2JNH05dFx5YzJhGUYAYJAFEaTEq36NAhTPy7_KekvzDFwt8wvQWdByvJIGWdEq6x2KpKD80&amp;t=632785713320000000" width="1" />
				<img height="152" alt="δ3.JPG" src="http://www.cnblogs.com/images/cnblogs_com/anf/δ3.JPG" width="434" border="0" />
				<br />      上面的计算进行迭代，直到 ó<sup>n </sup>和 ó<sup>n-1</sup>之间的差别小于一个阈值，如果计算没有聚合，我们就在迭代超过一定次数后停止。上图3的第三副图，就是5次迭代后的结果。表3时一些计算方法，后面的实验表明，C比较好。A叫做 sparce，B叫做 excepted，C叫做verbose<br /><br /><br /><strong>过滤<br /><br /></strong>      迭代出的结果是一种[多匹配]，可能包含有用的匹配子集。<br />      三个步骤：<br />            1。用程序定义的[限制条件]进行过滤。<br />            2。用双向图中的匹配上下文技术进行过滤<br />            3。比较各种技术的有效性（满足用户需求的能力）<br />      限制：主要有两种，一个是[类型]限制，比如只考虑[列]的匹配（匹配双方都是列）。第二个是 cardinality 限制，即模式S1中的所有元素都要在S2中有一个映射。<br /><br />stable marriage问题：n女和n男配对，不存在这样的两对 (x; y)和(x0; y0)，其中x喜欢 y0 胜过 y，而且 y0 喜欢 x 胜过 x0。具有stable marriage的匹配结果的total satisfaction可能会比不具有stable marriage的匹配结果还低！<br /><br /><strong>匹配质量的评估<br /></strong><br />   基本的评估思想，就是  用户对匹配结果做的修改越少，匹配质量就越高（修改结果包括去掉错误的pair，加上正确的pair）<br /><img height="88" alt="未命名1.JPG" src="http://www.cnblogs.com/images/cnblogs_com/anf/未命名1.JPG" width="372" border="0" />  n是找到的匹配数，m是理想的匹配数，c是用户作出修正的数目。<br /><br />from: <a href="http://www.cnblogs.com/anf/archive/2006/08/15/477700.html">http://www.cnblogs.com/anf/archive/2006/08/15/477700.html</a></p>
<img src ="http://www.blogjava.net/weidagang2046/aggbug/81825.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weidagang2046/" target="_blank">weidagang2046</a> 2006-11-17 18:25 <a href="http://www.blogjava.net/weidagang2046/articles/81825.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Java实现HTTP文件队列下载</title><link>http://www.blogjava.net/weidagang2046/articles/81696.html</link><dc:creator>weidagang2046</dc:creator><author>weidagang2046</author><pubDate>Fri, 17 Nov 2006 02:26:00 GMT</pubDate><guid>http://www.blogjava.net/weidagang2046/articles/81696.html</guid><wfw:comment>http://www.blogjava.net/weidagang2046/comments/81696.html</wfw:comment><comments>http://www.blogjava.net/weidagang2046/articles/81696.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weidagang2046/comments/commentRss/81696.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weidagang2046/services/trackbacks/81696.html</trackback:ping><description><![CDATA[
		<font face="Verdana">
				<strong>序言<br /><br /></strong>　　许多用户可能会遇到这样的情况：在网站上发现一个很好的资源，但是这个资源是分成了很多个文件存放的，如果想把它保存到本地，只有靠用户点击另存来完成保存，如果资源分了几百甚至上千上万，那简直是个灾难。 <br /><br />　　在Internet上很多的资源分成多个文件存放时，它的文件命名是有一定的规则的；正因如此，我们就可以用程序来完成这个资源的完全下载。<br /><br />　　<strong>1. 基础知识</strong><br /><br />　　在Internet上，我们要下载网站上的某个资源，我们会获得一个URL（Uniform Resource Locator），它是一个服务器资源定位的描述，下载的过程总是如下步骤:<br /><br />　　步骤1:客户端发起连接请求一个URL <br /><br />　　步骤2:服务器解析URL，并将指定的资源返回一个输入流给客户 <br /><br />　　步骤3:客户端接收输入流，将流中的内容存到文件 <br /><br />　　<strong>2. 网络连接的建立</strong><br /><br />　　Java提供了对URL访问和大量的流操作的的API，我们可以很容易的完成对网络上资源的存取,下面的代码段就完成了对一个网站的资源进行访问:<br /><br /></font>
		<font face="Verdana">
				<code>......<br />destUrl="http://www.ebook.com/java/网络编程001.zip";<br />url = new URL(destUrl);<br />httpUrl = (HttpURLConnection) url.openConnection();<br />//连接指定的网络资源<br />httpUrl.connect();<br />//获取网络输入流<br />bis = new BufferedInputStream(httpUrl.getInputStream());<br />......</code>
				<br />　　<strong>3. 代理的访问</strong><br /><br />　　Java 中通过代理服务器访问外网的方法已经是世人皆知的秘密了。这里就不再多描述了，访问的JAVA代码如下:<br /><br /></font>
		<font face="Verdana">
				<code>//设置代理服务器<br />System.getProperties().put("proxySet", "true");<br />System.getProperties().put("proxyHost", "10.154.134.110");<br />System.getProperties().put("proxyPort", "8080");</code>
				<br />　　<strong>4. 网络资源的保存</strong><br /><br />　　在上节中，我们已经获取了指定网络资源的输入流，接下来我们要完成的就是读取输入流中的所以内容，并将其保存在文件中。示例代码:<br /><br /></font>
		<font face="Verdana">
				<code>......<br />fos = new FileOutputStream(fileName);<br />if (this.DEBUG) <br />System.out.println("正在获取链接[" + destUrl + "]的内容...\n将其保存为文件[" + fileName +"]");<br /><br />//保存文件<br />while ( (size = bis.read(buf)) != -1)<br />fos.write(buf, 0, size);<br />......</code>
				<br />　　上面的示例代码就将网络资源的内容保存到了本地指定的文件中。<br /><br />　　<strong>5. 代码清单</strong><br /><br /></font>
		<code>
				<font face="Verdana">import java.io.*;<br />import java.net.*;<br />import java.util.*;<br /><br />/**<br />* ＜p＞Title: 个人开发的API＜/p＞<br />* ＜p＞Description: 将指定的HTTP网络资源在本地以文件形式存放＜/p＞<br />* ＜p＞Copyright: Copyright (c) 2004＜/p＞<br />* ＜p＞Company: NewSky＜/p＞<br />* @author MagicLiao<br />* @version 1.0<br />*/<br />public class HttpGet {<br /><br />　 public final static boolean DEBUG = true;//调试用<br />　 private static int BUFFER_SIZE = 8096;//缓冲区大小<br />　 private Vector vDownLoad = new Vector();//URL列表<br />　 private Vector vFileList = new Vector();//下载后的保存文件名列表<br /><br />　 /**<br />　 * 构造方法<br />　 */<br />　 public HttpGet() {}<br /><br />　 /**<br />　 * 清除下载列表<br />　 */<br />　 public void resetList() {<br />　　 vDownLoad.clear();<br />　　 vFileList.clear();<br />　 }<br /><br />　 /**<br />　 * 增加下载列表项<br />　 *<br />　 * @param url String<br />　 * @param filename String<br />　 */<br /><br />public void addItem(String url, String filename) {<br />　 vDownLoad.add(url);<br />　 vFileList.add(filename);<br />}<br /><br />　 /**<br />　 * 根据列表下载资源<br />　 */<br />public void downLoadByList() {<br />　 String url = null;<br />　 String filename = null;<br /><br />　 //按列表顺序保存资源<br />　 for (int i = 0; i ＜ vDownLoad.size(); i++) {<br />　　 url = (String) vDownLoad.get(i);<br />　　 filename = (String) vFileList.get(i);<br /><br />　　 try {<br />　　　 saveToFile(url, filename);<br />　　 }<br />　　 catch (IOException err) {<br />　　　 if (DEBUG) {<br />　　　　 System.out.println("资源[" + url + "]下载失败!!!");<br />　　　 }<br />　　 }<br />　 }<br /><br />　 if (DEBUG) {<br />　　 System.out.println("下载完成!!!");<br />　 }<br />}<br /><br />/**<br />* 将HTTP资源另存为文件<br />*<br />* @param destUrl String<br />* @param fileName String<br />* @throws Exception<br />*/<br />public void saveToFile(String destUrl, String fileName) throws IOException {<br />　 FileOutputStream fos = null;<br />　 BufferedInputStream bis = null;<br />　 HttpURLConnection httpUrl = null;<br />　 URL url = null;<br />　 byte[] buf = new byte[BUFFER_SIZE];<br />　 int size = 0;<br /><br />　 //建立链接<br />　 url = new URL(destUrl);<br />　 httpUrl = (HttpURLConnection) url.openConnection();<br />　 //连接指定的资源<br />　 httpUrl.connect();<br />　 //获取网络输入流<br />　 bis = new BufferedInputStream(httpUrl.getInputStream());<br />　 //建立文件<br />　 fos = new FileOutputStream(fileName);<br /><br />　 if (this.DEBUG) <br />　　 System.out.println("正在获取链接[" + destUrl + "]的内容...\n将其保存为文件[" + fileName + "]");<br /><br />　 //保存文件<br />　 while ( (size = bis.read(buf)) != -1) <br />　　 fos.write(buf, 0, size);<br /><br />　 fos.close();<br />　 bis.close();<br />　 httpUrl.disconnect();<br />}<br /><br />/**<br />* 设置代理服务器<br />*<br />* @param proxy String<br />* @param proxyPort String<br />*/<br />public void setProxyServer(String proxy, String proxyPort) {<br />　 //设置代理服务器 <br />　 System.getProperties().put("proxySet", "true");<br />　 System.getProperties().put("proxyHost", proxy);<br />　 System.getProperties().put("proxyPort", proxyPort);<br />}<br /><br />/**<br />* 设置认证用户名与密码<br />*<br />* @param uid String<br />* @param pwd String<br />*/<br />public void setAuthenticator(String uid, String pwd) {<br />Authenticator.setDefault(new MyAuthenticator(uid, pwd));<br />}<br /><br />/**<br />* 主方法(用于测试)<br />*<br />* @param argv String[]<br />*/<br />public static void main(String argv[]) {<br />　 HttpGet oInstance = new HttpGet();<br />　 try {<br />　　 //增加下载列表（此处用户可以写入自己代码来增加下载列表）<br />　　 oInstance.addItem("http://www.ebook.com/java/网络编程001.zip","./网络编程1.zip");<br />　　 oInstance.addItem("http://www.ebook.com/java/网络编程002.zip","./网络编程2.zip");<br />　　 oInstance.addItem("http://www.ebook.com/java/网络编程003.zip","./网络编程3.zip");<br />　　 oInstance.addItem("http://www.ebook.com/java/网络编程004.zip","./网络编程4.zip");<br />　　 oInstance.addItem("http://www.ebook.com/java/网络编程005.zip","./网络编程5.zip");<br />　　 oInstance.addItem("http://www.ebook.com/java/网络编程006.zip","./网络编程6.zip");<br />　　 oInstance.addItem("http://www.ebook.com/java/网络编程007.zip","./网络编程7.zip");<br />　　 //开始下载<br />　　 oInstance.downLoadByList();<br />　 }<br />　 catch (Exception err) {<br />　　 System.out.println(err.getMessage());<br />　 }<br />}<br />}<br /><br />from: <a href="http://www.1-100.org/other/11548.htm">http://www.1-100.org/other/11548.htm</a></font>
		</code>
<img src ="http://www.blogjava.net/weidagang2046/aggbug/81696.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weidagang2046/" target="_blank">weidagang2046</a> 2006-11-17 10:26 <a href="http://www.blogjava.net/weidagang2046/articles/81696.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于Linux的搜索引擎实现 </title><link>http://www.blogjava.net/weidagang2046/articles/81673.html</link><dc:creator>weidagang2046</dc:creator><author>weidagang2046</author><pubDate>Fri, 17 Nov 2006 01:35:00 GMT</pubDate><guid>http://www.blogjava.net/weidagang2046/articles/81673.html</guid><wfw:comment>http://www.blogjava.net/weidagang2046/comments/81673.html</wfw:comment><comments>http://www.blogjava.net/weidagang2046/articles/81673.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/weidagang2046/comments/commentRss/81673.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/weidagang2046/services/trackbacks/81673.html</trackback:ping><description><![CDATA[   搜索引擎是为用户提供快速获取网页信息的工具，其主要的功能是系统通过用户输入关键字，检索后端网页数据库，将相关网页的链接和摘要信息反馈给用户。从搜索的范围上一般分为站内网页搜索和全局网页搜索。随着网页数量的急剧增加，搜索引擎已经成为上网查询信息的必须手段，各个大型网站均已经提供网页数据搜索服务，并且出现了许多为大型网站提供专业搜索引擎服务的公司，如为Yahoo提供搜索服务的Google，为新浪网和263等国内网站提供服务的百度公司等。专业的搜索服务费用高而免费的搜索引擎软件基本都是基于英文的检索，所以都不太适合Intranet环境（如校园网等）的需要。 <br />搜索引擎的基本组成一般分为网页收集程序、网页后端数据组织存储、网页数据检索三部分。决定搜索引擎好坏的关键因素是数据查询的响应时间，即如何组织好满足全文检索需要的大量网页数据。 <br />GNU/Linux作为一个优秀的网络操作系统，其发行版本中集成了大量的网络应用软件，如 Web服务器（Apache ＋ PHP）、目录服务器（OpenLDAP）、脚本语言（Perl）、网页收集程序（Wget）等。所以，通过将它们集中进行应用，便可以实现一个简单、高效的搜索引擎服务器。 <br />一、基本组成和使用方法 <br />1、网页数据收集 <br />Wget程序是一个优秀的网页收集程序，它采用多线程设计能够方便地将网站内容镜像到本地目录中，并且能够灵活定制收集网页的类型、递归收集层次、目录限额、收集时间等。通过专用的收集程序完成网页的收集工作，既降低了设计的难度又提高了系统的性能。为了减小本地数据的规模，可只收集能够查询的html文件、txt文件、脚本程序asp和php只使用缺省的结果，而不收集如图形文件或是其他的数据文件。 <br />2、网页数据过滤 <br />由于html文件中存在大量的标记，如&lt;body&gt;&lt;table&gt;等，这些标记数据没有实际的搜索价值，所以加入数据库前必须对收集的数据进行过滤。Perl作为广泛使用的脚本语言，拥有非常强大而丰富的程序库，可以方便地完成网页的过滤。通过使用HTML-Parser库可以方便地提取出网页中包含的文字数据、标题数据、链接数据等。该程序库可以在www.cpan.net中下载，并且该网站收集的Perl程序涉及范围之广，远远超出我们的现象。 <br />3、目录服务 <br />目录服务是针对大量数据检索需要开发的服务，最早出现在X.500协议集中，后来扩展到TCP/IP中发展成为LDAP（Lightweight Directory Acess Protocol）协议，其相关的标准为1995年制定的RFC1777和1997年制定的RFC2251等。LDAP协议已经作为工业标准被Sun、Lotus、微软等公司广泛应用到其相关产品中，但是专用的基于Windows平台的目录服务器却较少见，OpenLDAP是免费的运行于Unix系统的目录服务器，其产品的性能优秀，已经被许多的Linux发行版本收集（Redhat、Mandrake等），并且提供了包括C、Perl、PHP等的开发接口。 <br />使用目录服务技术代替普通的关系数据库作为网页数据的后端存取平台主要基于目录服务的技术优势。目录服务简化了数据处理类型，去掉了通用关系数据库的费时的事务机制，而是采用全局替换的策略对数据进行更新，其应用的重点是大量数据的检索服务（一般数据更新和检索的频率比例要求在1:10以上），强调检索速度和全文查询，提供完整的数据备份，非常适合搜索引擎之类服务的需要。从目录服务技术解决问题的重点不难看出其在数据检索上的优势，它的提出时间远远落后于关系数据库的提出时间，实际上反映了根据具体问题优化数据解决方案的原则。这与目前广泛存在的凡是涉及大量数据处理必选SQL Server的处理方法形成鲜明对比。 <br />通过选用成熟的目录服务技术提高网页查询的效率，能够简洁有效地提高数据处理能力。这也充分显示了GNU/Linux系统运行开放软件的优势，毕竟不能方便地获得运行于其他平台的目录服务器。 <br />4、查询程序设计 <br />搜索引擎的前端界面是网页，用户通过在特定的网页中输入关键字提交给Web服务器进行处理。运行在Apache Web服务器上的PHP脚本通过运行其相关ldap函数便可以执行关键字的查询工作。主要进行的工作是根据关键字构造查询、向目录服务器提交查询、显示查询结果等。Linux + Apache + PHP作为广泛使用Web服务器，与WinNT + IIS + ASP相比其性能毫不逊色，在目前的Linux发行版本中都集成了Apache + PHP 以及缺省的ldap、pgsql、imap等模块。 <br />5、计划任务 <br />搜索引擎的网页数据收集、数据过滤、加入目录数据库等工作都应该是自动完成的，在UNIX系统中有cron进程来专门完成按照特定时间调度任务，为了不影响系统的运行，一般可以把这些工作安排到深夜进行。 <br />二、具体步骤和注意事项 <br />1、配置Wget软件 <br />在RedHat 6.2发行版中已经集成了该软件包，可以直接进行安装。将需要镜像的站点地址编辑为一个文件中，通过 -I 参数读入该文件；为镜像的站点指定一个本地下载目录；为了避免内部网中链接的重复引用，一般只镜像该站点内的数据；还可以根据网站的具体情况，指定其镜像的深度。 <br />2、配置Openldap服务 <br />在RedHat 6.2发行版中已经集成了Openldap-1.2.9，其配置文件存放在/etc/openldap的目录中。主要的配置文件是slapd.conf，关键要打开对检索速度至关重要的index选项，可以使用setup工具，将ldap在系统引导后作为缺省服务启动。 <br />Ldap服务可以通过文本文件方式存放数据，即LDIF文件格式。使用此方式可以高效地更新目录服务数据，需要注意LDIF格式是通过空行对数据进行分隔的，并且通过运行ldif2lbm将LDIF格式数据导入目录数据库中时需要暂停目录服务。 <br />3、编制数据过滤和LDIF文件生成脚本 <br />为了方便地过滤网页数据，可以调用Perl的HTML-Parser库函数，该程序包下载后需要进行编译，在eg目录下生成了相关的htext，htitle程序，在Perl中可以通过调用外部程序的方式运行该程序，并对其过滤结果通过重定向的方法生成临时文件。本搜索引擎设计的目录数据属性有dn 、link、title、modifydate、contents，其中的dn通过Link进行唯一性标识，将过滤后的网页文本内容通过/usr/sbin/ldif程序进行自动编码后放入LDIF文件中。 <br />基本的LDIF文件格式如下： <br />dn: dc=27jd,dc=zzb <br />objectclass: top <br />objectclass: organization <br /> <br />dn: link= http://freemail.27jd.zzh/index.html, dc=27jd ,dc=zzb <br />link: http://freemail.27jd.zzh/index.html <br />title: Webmail主页 <br />modifydate: 2001年2月8日 <br />contents:: <br />CgpXZWJtYWls1vfSswoKCgoKIKHvoaG7ttOtyrnTw1dlYm1haWzPtc2zoaGh7yDO0t <br />KqyerH69PKz+QhISFPdXRsb29rxeTWw6O6U01UUDogZnJlZW1haWwuMjdqZC56emJQ <br />T1AzOiBmcm <br />VlbWFpbC4yN2pkLnp6YkROUyA6IDExLjk5LjY0Ljiy4srU08O7p6O6bWFpbGd1ZXN00 <br />8O7p7/awe <br />6jum1haWxndWVzdNLR16Ky4dPDu6cg08O7p8P7OkAgZnJlZW1haWwuMjdqZC56emK/ <br />2sHuOqChoa <br />AgIKHyzOG5qbf+zvEgofKzo7z7zsrM4iCh8s2o0bbCvKHyICCh8sq1z9bUrcDtIKHywfTR1 <br />LK+of <br />IgofK8vMr1sr/W99Kzsb7Ptc2z08nK1NHpvLzK9bK/zfjC59bQ0MS9qMGius3OrLukCgoK <br />CqAKCg <br />o= <br />objectclass:webpage <br /> <br />基本的slapd.conf文件如下： <br />defaultaccess read <br />include /etc/openldap/slapd.at.conf <br />#include /etc/openldap/slapd.oc.conf <br />schemacheck off <br />sizelimit 20000 <br />pidfile /var/run/slapd.pid <br />argsfile /var/run/slapd.args <br />####################################################################### <br /># ldbm database definitions <br />####################################################################### <br />database ldbm <br />dbcachesize 1000000 <br />index contents,title <br />suffix "dc=27jd, dc=zzb" <br />directory /usr/tmp <br />rootdn "cn=root,dc=27jd, dc=zzb" <br />rootpw secret <br /> <br />通过对一个4万个网页（约300M左右）的本地html文件目录进行过滤后生成的LDIF文件约180M左右，如果只取文字数据的前400个字符作为网页内容，则生成文件约35M左右。 <br />4、配置PHP+LDAP服务 <br />在Redhat6.2中已经集成了PHP3和php-ldap模块，选择完全安装时便已经安装到/usr/lib/apache目录中，注意检查/etc/httpd/php3.ini中的动态扩展（Dynamic Extensions）中的extension=ldap.so是否被选择。PHP3中提供了丰富的LDAP存取函数，能够方便完成对目录数据的搜索功能。有关Apach + PHP编程方面的资料较多，在此不在赘述。注意在PHP3中的LDAP搜索函数ldap_search不能处理其返回结果超过目录服务设定的最大检索数据，所以可以根据具体情况，在slapd的配置文件中设定较大的检索数据限制(sizelimit)，此问题在PHP4中已经解决。 <br />5、任务调度 <br />在Redhat6.2中已经集成了crond并且缺省安装后便已经启动。其相关配置文件有/etc/crontab、/etc/cron.daily、/etc/cron.hourly、/etc/weekly、/etc/monthly，你只需要根据数据的更新频度，将网页收集、网页过滤、生成LDIF文件、停止目录服务、更新目录数据、重新启动目录服务，作为一个简单的Shell程序放入到相应的目录中即可。 <br />三、效果与思考 <br />以上简单的介绍了我们的搜索引擎的实现方法和注意事项，这仅仅是我们在对GNU/Linux了解得非常肤浅的情况下设计的以目录服务为核心的满足内部网需要的搜索引擎系统，并不能代表GNU/Linux和它集成的大量软件的真正实力。 <br />通过在一台安装RedHat Linux 6.2 的Sparc Ultra 250上实际测试，对拥有4万个网页的目录数据进行搜索时，基于上述方法设计的搜索引擎响应速度一般在3秒左右，目录数据完全更新大约需要4小时左右，能够满足内部网的需要。实际上，限制搜索响应速度的关键是PHP3的ldap_search函数没有提供数据限制的功能，导致在查询结果集过大时系统响应速度变慢，因为每次用户能够浏览的查询结果实际是非常少的，而服务器端每次的查询总是返回全部结果，在PHP4中的ldap_search通过指定sizelimit参数，能够有效解决该问题。 <br />目录服务的应用范围非常广泛，实际上作为大型的信息站点为了提高客户访问效率，都或多或少采用了目录服务的技术。目录服务根据具体的应用需求的优化设计方法，对我们决定应用系统的开发无疑是一个启发，应该说在基于索引信息的领域LDAP服务远远优于传统的关系数据库系统。 <br />基于GNU/Linux进行网络服务器程序设计，能够充分体会到开放源代码的魅力和实力，它既能够简化系统的设计，又大大地提高了工作效率，同时也有效降低了系统的成本。程序设计由一切从零开始的复杂繁琐的重复劳动，简化为问题抽象、功能分解、查找资源、组合系统四个部分，更加强调对系统的认识、开阔的视野和学习的能力，同时开放源代码也为系统进一步优化提供了坚实的基础。 <br /><img src ="http://www.blogjava.net/weidagang2046/aggbug/81673.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/weidagang2046/" target="_blank">weidagang2046</a> 2006-11-17 09:35 <a href="http://www.blogjava.net/weidagang2046/articles/81673.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>