第1章引言
1.1nutch和solr
Nutch是一个开源的、Java实现的搜索引擎。它提供了我们运行自己的搜索引擎所需的全部工具。
Solr拥有像web-services API的独立的企业级搜索服务器。用XML通过HTTP向它添加文档(称为做索引),通过HTTP查询返回XML结果。
1.2研究nutch的原因
可能有的朋友会有疑问,我们有google,有百度,为何还需要建立自己的搜索引擎呢?这里我列出3点原因:
-
透明度:nutch是开放源代码的,因此任何人都可以查看他的排序算法是如何工作的。
-
商业的搜索引擎排序算法都是保密的,我们无法知道为什么搜索出来的排序结果是如何算出来的。更进一步,一些搜索引擎允许竞价排名,比如百度,这样的索引结果并不是和站点内容相关的。因此nutch对学术搜索和政府类站点的搜索来说,是个好选择,因为一个公平的排序结果是非常重要的。
-
对搜索引擎的理解:我们并没有google的源代码,因此学习搜索引擎Nutch是个不错的选择。了解一个大型分布式的搜索引擎如何工作是一件让人很受益的事情。在写Nutch的过程中,从学院派和工业派借鉴了很多知识:比如,Nutch的核心部分目前已经被重新用Map Reduce实现了。Map Reduce是一个分布式的处理模型,最先是从Google实验室提出来的。并且Nutch也吸引了很多研究者,他们非常乐于尝试新的搜索算法,因为对Nutch来说,这是非常容易实现扩展的。
-
扩展性:你是不是不喜欢其他的搜索引擎展现结果的方式呢?那就用Nutch写你自己的搜索引擎吧。Nutch是非常灵活的:他可以被很好的客户订制并集成到你的应用程序中,使用Nutch的插件机制,Nutch可以作为一个搜索不同信息载体的搜索平台。当然,最简单的就是集成Nutch到你的站点,为你的用户提供搜索服务。
-
1.3nutch的目标
nutch致力于让每个人能很容易,同时花费很少就可以配置世界一流的Web搜索引擎.为了完成这一宏伟的目标, nutch必须能够做到:
• 每个月取几十亿网页
• 为这些网页维护一个索引
• 对索引文件进行每秒上千次的搜索
• 提供高质量的搜索结果
• 以最小的成本运作
这将是一个巨大的挑战。
1.4nutch VS lucene
简单的说:
Lucene不是完整的应用程序,而是一个用于实现全文检索的软件库。
Nutch是一个应用程序,可以以Lucene为基础实现搜索引擎应用。
Lucene为Nutch提供了文本索引和搜索的API。一个常见的问题是;我应
该使用Lucene还是Nutch?最简单的回答是:如果你不需要抓取数据的话,应该使用Lucene。常见的应用场合是:你有数据源,需要为这些数据提供一个搜索页面。
在这种情况下,最好的方式是直接从数据库中取出数据并用Lucene API建立索引。
第2章安装与配置
-
安装环境: Ubuntu12.04 LTS
-
所安装软件: JDK1.6.0_29
apache-nutch-1.5-bin.tar.gz
solr3.6
IKAnalyzer3.2.3
tomcat7.0
-
我将软件默认安装在当前用户的主文件夹下(/用户)
-
下载网址:
jdk:http://www.oracle.com/technetwork/java/javase/downloads/index.html
nutch:http://www.apache.org/dyn/closer.cgi/nutch/
solr:http://mirror.bjtu.edu.cn/apache/lucene/solr/3.6.0/
IKAnalyzer:http://code.google.com/p/ik-analyzer/
tomcat:http://tomcat.apache.org/download-70.cgi#7.0.27
2.1安装和配置JDK,Tomcat
网上很多例子了。
2.2安装和配置nutch
到用户主目录:
cd~
建立文件夹:
mkdirnutch
将文件拷贝到~/hadoop/nutch目录,解压缩:
tar-zxvf apache-nutch-1.5-bin.tar.gz
如果没用权限,可以使用chmod和chown授权
验证一下,执行
bin/nutch
2.3安装和配置solr
到用户主目录:
cd~
进入hadoop目录,拷贝apache-solr-3.6.0.tgz,解压缩:
tar-zxvf apache-solr-3.6.0.tgz
1)拷贝[solr_home]/dist/apache-solr-3.6.0.war的文件到tomcat/webapps目录下,并且改名solr.war
2)将[solr_home]\example\下的solr目录拷贝到任意位置,我是放在:~/tomcat7/solr下
3)在tomcat目录下的conf\Catalina\localhost目录中(如果没有则手工创建该目录)创建solr.xml文件,文件内容如下:
<ContextdocBase="[tomat_home]/webapps/solr.war" debug="0"crossContext="true" >
<Environmentname="solr/home" type="java.lang.String"value="[tomcat_home]/solr" override="true"/>
</Context>
4)修改tomcat的server.xml文件,找到<Connectorport="8080" … 项(假设tomcat监听8080端口),添加编码方式,修改后如下<Connectorport="8080" URIEncoding="UTF-8"
5)启动tomcat,输入http://localhost:8080/solr/,出现欢迎界面则表示配置成功
2.4配置1KAnalyzer到solr
拷贝IKAnalyzer2012.jar到webapps中的solr的lib目录下
配置项目中文分词:
编辑[tomat_home]/solr/conf/schema.xml,在<Types>下添加以下内容:
<!--add 1kanalyzer configuration-->
<fieldType name=
"text"
class
=
"solr.TextField"
>
<analyzer
class
=
"org.wltea.analyzer.lucene.IKAnalyzer"
/>
<analyzer type=
"index"
>
<tokenizer
class
=
"org.wltea.analyzer.solr.IKTokenizerFactory"
isMaxWordLength=
"false"
/>
<filter
class
=
"solr.StopFilterFactory"
ignoreCase=
"true"
words=
"stopwords.txt"
/>
<filter
class
=
"solr.WordDelimiterFilterFactory"
generateWordParts=
"1"
generateNumberParts=
"1"
catenateWords=
"1"
catenateNumbers=
"1"
catenateAll=
"0"
splitOnCaseChange=
"1"
/>
<filter
class
=
"solr.LowerCaseFilterFactory"
/>
<filter
class
=
"solr.EnglishPorterFilterFactory"
protected
=
"protwords.txt"
/>
<filter
class
=
"solr.RemoveDuplicatesTokenFilterFactory"
/>
</analyzer>
<analyzer type=
"query"
>
<tokenizer
class
=
"org.wltea.analyzer.solr.IKTokenizerFactory"
isMaxWordLength=
"false"
/>
<filter
class
=
"solr.StopFilterFactory"
ignoreCase=
"true"
words=
"stopwords.txt"
/>
<filter
class
=
"solr.WordDelimiterFilterFactory"
generateWordParts=
"1"
generateNumberParts=
"1"
catenateWords=
"1"
catenateNumbers=
"1"
catenateAll=
"0"
splitOnCaseChange=
"1"
/>
<filter
class
=
"solr.LowerCaseFilterFactory"
/>
<filter
class
=
"solr.EnglishPorterFilterFactory"
protected
=
"protwords.txt"
/>
<filter
class
=
"solr.RemoveDuplicatesTokenFilterFactory"
/>
</analyzer>
</fieldType>
|
然后在<fields>下添加:
<field name=
"name1"
type=
"text"
indexed=
"true"
stored=
"true"
required=
"true"
/>
|
重新启动tomcat,进入
http://localhost:8080/solr/admin/analysis.jsp
输入“中华人民共和国”,点击analyze,得到结果如下:
注意:此处的verbose output 和highlight matches选项要勾选,才会显示如下的结果:
第3章nutch实验
Nutch的爬虫有两种方式
•爬行企业内部网(Intranetcrawling)。针对少数网站进行,用crawl命令。
•爬行整个互联网。使用低层的inject,generate, fetch和updatedb命令,
具有更强的可控制性。
3.1爬取163
进入[nutch_home]
编辑conf/nutch-site.xml:
<?xml version=
"1.0"
?>
<?xml-stylesheet type=
"text/xsl"
href=
"configuration.xsl"
?>
<!-- Put site-specific property overrides in
this
file. -->
<configuration>
<property>
<name>http.agent.name</name>
<value>myagent</value>
<description>HTTP
'User-Agent'
request header. MUST NOT be empty -
please set
this
to a single word uniquely related to your organization.
NOTE: You should also check other related properties:
http.robots.agents
http.agent.description
http.agent.url
http.agent.email
http.agent.version
and set their values appropriately.
</description>
</property>
<property>
<name>http.agent.description</name>
<value></value>
<description>Further description of our bot-
this
text is used in
the User-Agent header. It appears in parenthesis after the agent name.
</description>
</property>
<property>
<name>http.agent.url</name>
<value></value>
<description>A URL to advertise in the User-Agent header. This will
appear in parenthesis after the agent name. Custom dictates that
this
should be a URL of a page explaining the purpose and behavior of
this
crawler.
</description>
</property>
<property>
<name>http.agent.email</name>
<value></value>
<description>An email address to advertise in the HTTP
'From'
request
header and User-Agent header. A good practice is to mangle
this
address (e.g.
'info at example dot com'
) to avoid spamming.
</description>
</property>
</configuration>
|
创建目录urls,并建立文件seed.txt,加入
http://www.163.com
编辑conf/regex-urlfilter.txt
修改以下部分:
# accept anything else
+^http://([a-z0-9]*\.)*www.163.com/
执行爬取命令:
bin/nutch crawl urls -dir crawl -depth 3 -topN 5
-
urls是存放163网址的文件夹目录
-
-dir crawl.demo是抓取的页面的存放目录
-
-depth指爬行的深度,这里处于测试的目的,选择深度为2 ,完
全爬行一般可设定为10左右
-
-threads指定并发的进程这是设定为4
-
-topN指在每层的深度上所要抓取的最大的页面数,
完全抓取可设定为1万到100万,这取决于网站资源数量
爬取资源并且添加索引:
bin/nutch crawl urls -solr http://localhost:8080/solr/ -depth 3 -topN 5
执行结果如下:
3.2solrj访问solr
3.2.1solr基础
因为 Solr 包装并扩展了 Lucene,所以它们使用很多相同的术语。更重要的是,Solr创建的索引与Lucene搜索引擎库完全兼容。通过对Solr进行适当的配置,某些情况下可能需要进行编码,Solr可以阅读和使用构建到其他Lucene应用程序中的索引。
在Solr和Lucene中,使用一个或多个Document来构建索引。Document包括一个或多个Field。Field包括名称、内容以及告诉Solr如何处理内容的元数据。例如,Field可以包含字符串、数字、布尔值或者日期,也可以包含你想添加的任何类型,只需用在solr的配置文件中进行相应的配置即可。Field可以使用大量的选项来描述,这些选项告诉Solr在索引和搜索期间如何处理内容。现在,查看一下表1中列出的重要属性的子集:
属性名称 | 描述 |
Indexed | Indexed Field可以进行搜索和排序。你还可以在indexed Field上运行Solr分析过程,此过程可修改内容以改进或更改结果。 |
Stored | stored Field内容保存在索引中。这对于检索和醒目显示内容很有用,但对于实际搜索则不是必需的。例如,很多应用程序存储指向内容位置的指针而不是存储实际的文件内容。 |
3.2.2solr索引操作
在Solr中,通过向部署在servlet容器中的Solr Web应用程序发送HTTP请求来启动索引和搜索。Solr接受请求,确定要使用的适当SolrRequestHandler,然后处理请求。通过HTTP以同样的方式返回响应。默认配置返回Solr的标准XML响应。你也可以配置Solr的备用响应格式,如json、csv格式的文本。
索引就是接受输入元数据(数据格式在schema.xml中进行配置)并将它们传递给Solr,从而在HTTPPost XML 消息中进行索引的过程。你可以向Solr索引servlet传递四个不同的索引请求:
add/update允许您向Solr添加文档或更新文档。直到提交后才能搜索到这些添加和更新。
commit告诉Solr,应该使上次提交以来所做的所有更改都可以搜索到。
optimize重构Lucene的文件以改进搜索性能。索引完成后执行一下优化通常比较好。如果更新比较频繁,则应该在使用率较低的时候安排优化。一个索引无需优化也可以正常地运行。优化是一个耗时较多的过程。
delete可以通过id或查询来指定。按id删除将删除具有指定id的文档;按查询删除将删除查询返回的所有文档。
Lucene中操作索引也有这几个步骤,但是没有更新。Lucene更新是先删除,然后添加索引。因为更新索引在一定情况下,效率没有先删除后添加的效率好。
3.2.3solr搜索
添加文档后,就可以搜索这些文档了。Solr接受HTTPGET和HTTPPOST查询消息。收到的查询由相应的SolrRequestHandler进行处理。
solr查询参数描述:
参数 | 描述 | 示例 |
q | Solr中用来搜索的查询。有关该语法的完整描述,请参阅 参考资料。可以通过追加一个分号和已索引且未进行断词的字段(下面会进行解释)的名称来包含排序信息。默认的排序是scoredesc,指按记分降序排序。 | q=myField:JavaAND otherField:developerWorks; dateasc此查询搜索指定的两个字段,并根据一个日期字段对结果进行排序。 |
start | 将初始偏移量指定到结果集中。可用于对结果进行分页。默认值为0。 | start=15 返回从第15个结果开始的结果。 |
rows | 返回文档的最大数目。默认值为 10。 | rows=25,返回25个结果集 |
fq | 提供一个可选的筛选器查询。查询结果被限制为仅搜索筛选器查询返回的结果。筛选过的查询由Solr进行缓存。它们对提高复杂查询的速度非常有用。 | 任何可以用 q参数传递的有效查询,排序信息除外。 |
hl | 当 hl=true时,在查询响应中醒目显示片段。默认为false。参看醒目显示参数(见 参考资料)。 | hl=true |
fl | 作为逗号分隔的列表指定文档结果中应返回的 Field集。默认为 “*”,指所有的字段。“score”指还应返回记分。 | *,score |
sort | 排序,对查询结果进行排序,参考 | sort=dateasc,price desc |
3.2.4solr模式
上面有提到schema.xml这个配置,这个配置可以在你下载solr包的安装解压目录的apache-solr-3.6.0\example\solr\conf中找到,它就是solr模式关联的文件。打开这个配置文件,你会发现有详细的注释。
模式组织主要分为三个重要配置
types部分是一些常见的可重用定义,定义了Solr(和Lucene)如何处理Field。也就是添加到索引中的xml文件属性中的类型,如int、text、date等
fileds是你添加到索引文件中出现的属性名称,而声明类型就需要用到上面的types
其他配置有
uniqueKey唯一键,这里配置的是上面出现的fileds,一般是id、url等不重复的。在更新、删除的时候可以用到。
defaultSearchField默认搜索属性,如q=solr就是默认的搜索那个字段
solrQueryParser查询转换模式,是并且还是或者(and/or)
3.2.5索引配置
Solr性能因素,来了解与各种更改相关的性能权衡。
表1概括了可控制Solr索引处理的各种因素:
因素 | 描述 |
useCompoundFile | 通过将很多 Lucene内部文件整合到单一一个文件来减少使用中的文件的数量。这可有助于减少Solr使用的文件句柄数目,代价是降低了性能。除非是应用程序用完了文件句柄,否则false的默认值应该就已经足够。 |
mergeFactor | 决定低水平的 Lucene段被合并的频率。较小的值(最小为2)使用的内存较少但导致的索引时间也更慢。较大的值可使索引时间变快但会牺牲较多的内存。 |
maxBufferedDocs | 在合并内存中文档和创建新段之前,定义所需索引的最小文档数。段是用来存储索引信息的Lucene文件。较大的值可使索引时间变快但会牺牲较多的内存。 |
maxMergeDocs | 控制可由 Solr合并的 Document的最大数。较小的值 (<10,000) 最适合于具有大量更新的应用程序。 |
maxFieldLength | 对于给定的 Document,控制可添加到Field的最大条目数,进而截断该文档。如果文档可能会很大,就需要增加这个数值。然而,若将这个值设置得过高会导致内存不足错误。 |
unlockOnStartup | unlockOnStartup告知Solr忽略在多线程环境中用来保护索引的锁定机制。在某些情况下,索引可能会由于不正确的关机或其他错误而一直处于锁定,这就妨碍了添加和更新。将其设置为true可以禁用启动锁定,进而允许进行添加和更新。 |
3.2.6查询处理配置
<maxBooleanClauses>标记定义了可组合在一起形成一个查询的子句数量的上限。对于大多数应用程序而言,默认的1024就应该已经足够;然而,如果应用程序大量使用了通配符或范围查询,增加这个限值将能避免当值超出时,抛出TooManyClausesException。
若应用程序预期只会检索Document上少数几个Field,那么可以将<enableLazyFieldLoading>属性设置为true。懒散加载的一个常见场景大都发生在应用程序返回和显示一系列搜索结果的时候,用户常常会单击其中的一个来查看存储在此索引中的原始文档。初始的显示常常只需要显示很短的一段信息。若考虑到检索大型Document的代价,除非必需,否则就应该避免加载整个文档。
<query>部分负责定义与在Solr中发生的事件相关的几个选项。Searcher的Java类来处理Query实例。要改进这一设计和显著提高性能,把这些新的Searcher联机以便为现场用户提供查询服务之前,先对它们进行“热身”。<query>部分中的<listener>选项定义newSearcher和firstSearcher事件,您可以使用这些事件来指定实例化新搜索程序或第一个搜索程序时应该执行哪些查询。如果应用程序期望请求某些特定的查询,那么在创建新搜索程序或第一个搜索程序时就应该反注释这些部分并执行适当的查询。
solrconfig.xml文件的剩余部分,除<admin>之外,涵盖了与缓存、复制 和 扩展或定制 Solr有关的项目。admin部分让您可以定制管理界面。有关配置admin节的更多信息,请参看solrconfig.xml文件中的注释。
3.2.7监视、记录和统计数据
用于监视、记录和统计数据的Solr管理选项
菜单名 | URL | 描述 |
Statistics | Statistics管理页提供了与Solr性能相关的很多有用的统计数据。这些数据包括: 关于何时加载索引以及索引中有多少文档的信息。 关于用来服务查询的SolrRequestHandler的有用信息。 涵盖索引过程的数据,包括添加、删除、提交等的数量。 缓存实现和 hit/miss/eviction信息 | |
Info | 有关正在运行的 Solr的版本以及在当前实现中进行查询、更新和缓存所使用的类的详细信息。此外,还包括文件存于Solrsubversion存储库的何处的信息以及对该文件功能的一个简要描述。 | |
Distribution | 显示与索引发布和复制有关的信息。更多信息,请参见“发布和复制” 一节。 | |
Ping | 向服务器发出 ping请求,包括在 solrconfig.xml文件的 admin部分定义的请求。 | |
Logging | 让您可以动态更改当前应用程序的日志记录等级。更改日志记录等级对于调试在执行过程中可能出现的问题非常有用。 | |
properties | http://localhost:8080/solr/admin/get-properties.jsp | 显示当前系统正在使用的所有 Java系统属性。Solr支持通过命令行的系统属性替换。有关实现此特性的更多信息,请参见solrconfig.xml文件。 |
Thread dump | http://localhost:8080/solr/admin/threaddump.jsp | thread dump选项显示了在JVM中运行的所有线程的堆栈跟踪信息。 |
3.2.8智能缓存
智能缓存是让Solr得以成为引人瞩目的搜索服务器的一个关键性能特征。Solr提供了四种不同的缓存类型,所有四种类型都可在solrconfig.xml的<query>部分中配置。solrconfig.xml文件中所用的标记名列出了这些缓存类型:
缓存标记名 | 描述 | 能否自热 |
filterCache | 通过存储一个匹配给定查询的文档 id的无序集,过滤器让 Solr能够有效提高查询的性能。缓存这些过滤器意味着对Solr的重复调用可以导致结果集的快速查找。更常见的场景是缓存一个过滤器,然后再发起后续的精炼查询,这种查询能使用过滤器来限制要搜索的文档数。 | 可以 |
queryResultCache | 为查询、排序条件和所请求文档的数量缓存文档 id的有序 集合。 | 可以 |
documentCache | 缓存 LuceneDocument,使用内部 Lucene文档 id(以便不与Solr惟一id相混淆)。由于Lucene的内部Document id可以因索引操作而更改,这种缓存不能自热。 | 不可以 |
Named caches | 命名缓存是用户定义的缓存,可被 Solr定制插件 所使用。 | 可以,如果实现了 org.apache.solr.search.CacheRegenerator的话。 |
每个缓存声明都接受最多四个属性:
class是缓存实现的Java名。
size是最大的条目数。
initialSize是缓存的初始大小。
autoWarmCount是取自旧缓存以预热新缓存的条目数。如果条目很多,就意味着缓存的hit会更多,只不过需要花更长的预热时间。