自己动手搭建搜索工具

作者 白宁超

2016年4月12日16:31:48

摘要:搜索已经作为生活中不可缺少的一部分,诸如:百度、google、还是在微信上寻找好友或者通过一段文本查找关键字。另外亚马逊、京东、天猫、苏宁等电商在搜索中也是别有洞天(多面搜索等)。对于开发人员,搜索往往是大部分应用的关键功能,特别是对大规模文本数据驱动应用更是如此。另一类搜索像语音智能检索,其采用分类、聚类、神经网络等方法进行模型评估,反馈给用户比较理想的匹配结果,这里需要强调的是其采用评分机制反馈的模糊近似查询结果,与传统精确采用是不一样的。这种结果的反馈评分主要依托正确率和召回率。这里自己构建搜索工具好处在于:灵活性、开发费用低、自己更了解自己的搜索工具、价格当然是免费的啦。本文作者花费大量时间,经过资料收集,研究和实验所得,旨在技术分享。(本文原创,转载需说明出处:自己动手搭建搜索工具。)

目录


【文本挖掘(0)】快速了解什么是自然语言处理

【文本挖掘(1)】OpenNLP:驾驭文本,分词那些事

【文本挖掘(2)】【NLP】Tika 文本预处理:抽取各种格式文件内容

【文本挖掘(3)】自己动手搭建搜索工具

1 Apache Solr搜索服务器简介

1.1. Solr 是什么?

Solr它是一种开放源码的、基于 Lucene Java 的搜索服务器,易于加入到 Web 应用程序中。Solr 提供了层面搜索(就是统计)、命中醒目显示并且支持多种输出格式(包括XML/XSLT 和JSON等格式)。它易于安装和配置,而且附带了一个基于HTTP 的管理界面。可以使用 Solr 的表现优异的基本搜索功能,也可以对它进行扩展从而满足企业的需要。Solr的特性包括:

  • 高级的全文搜索功能
  • 专为高通量的网络流量进行的优化
  • 基于开放接口(XML和HTTP)的标准
  • 综合的HTML管理界面
  • 可伸缩性-能够有效地复制到另外一个Solr搜索服务器
  • 使用XML配置达到灵活性和适配性
  • 可扩展的插件体系

2. Lucene 是什么?

Lucene是一个基于Java的全文信息检索工具包,它不是一个完整的搜索应用程序,而是为你的应用程序提供索引和搜索功能。Lucene 目前是 Apache Jakarta(雅加达) 家族中的一个开源项目。也是目前最为流行的基于Java开源全文检索工具包。目前已经有很多应用程序的搜索功能是基于 Lucene ,比如Eclipse 帮助系统的搜索功能。Lucene能够为文本类型的数据建立索引,所以你只要把你要索引的数据格式转化的文本格式,Lucene 就能对你的文档进行索引和搜索。

3. Solr vs Lucene

Solr与Lucene 并不是竞争对立关系,恰恰相反Solr 依存于Lucene,因为Solr底层的核心技术是使用Lucene 来实现的,Solr和Lucene的本质区别有以下三点:搜索服务器,企业级和管理。Lucene本质上是搜索库,不是独立的应用程序,而Solr是。Lucene专注于搜索底层的建设,而Solr专注于企业应用。Lucene不负责支撑搜索服务所必须的管理,而Solr负责。所以说,一句话概括 Solr: Solr是Lucene面向企业搜索应用的扩展。Solr使用Lucene并且扩展了它!一个真正的拥有动态字段(Dynamic Field)和唯一键(Unique Key)的数据模式(Data Schema)

  • 对Lucene查询语言的强大扩展!
  • 支持对结果进行动态的分组和过滤
  • 高级的,可配置的文本分析
  • 高度可配置和可扩展的缓存机制
  • 性能优化
  • 支持通过XML进行外部配置
  • 拥有一个管理界面
  • 可监控的日志
  • 支持高速增量式更新(Fast incremental Updates)和快照发布(Snapshot Distribution)

2 安装下载最新的Solr

1)本文使用Solr4.8版本,Solr 最新版本有出入请以官方网站内容为准。Solr官方网站下载地址:http://www.apache.org/dyn/closer.cgi/lucene/solr/

Solr 程序包的部分目录结构

dist :存放Solr 构建完成的JAR 文件、WAR 文件和Solr 依赖的JAR 文件。

example :是一个安装好的Jetty 中间件,其中包括一些样本数据和Solr 的配置信息。

example/etc :Jetty 的配置文件。

example/multicore :当安装Slor multicore 时,用来放置多个Solr 主目录。

example/solr :默认安装时一个Solr 的主目录。

example/webapps :Solr 的WAR 文件部署在这里。

Solr 的主目录展开后为如下结构:

bin :建议将集群复制脚本放在这个目录下。

conf :放置配置文件。

conf/schema.xml :建立索引的schema 包含了字段类型定义和其相关的分析器。

conf/solrconfig.xml :这个是Solr 主要的配置文件。

conf/xslt :包含了很多xslt 文件,这些文件能将Solr 的XML 的查询结果转换为特定的格式,比如:Atom/RSS。

data :放置Lucene 产生的索引数据。

lib :放置可选的JAR 文件比如对Slor 扩展的插件,这些JAR 文件将会在Solr 启动时加载。

2)在example目录有start.jar文件,启动:浏览器访问:http://localhost:8983/solr/,你看到的就是solr的管理界面

cd  C:\\Users\\bnc\\Desktop\\NPL\\apache-solr\\example
java -jar start.jar

  

目前你看到的界面没有任何数据,你可以通过POSTing命令向Solr中添加(更新)文档,删除文档,在exampledocs目录包含一些示例文件,运行命令:

cd exampledocs
java -jar post.jar *.xml

3 Solr在tomcat下配置集成与启动验证

1  下载solr源文件与tomcat源文件

2  建立文件夹命名solr放置3个文件夹:

solr-4.8.0\example\solr文件夹改名home

tomcat改名server

solr-4.8.0\dist下solr-4.8.0.war改名solr.war放在solr\server\webapps下

3  打开solr\server\conf下server.xml  <Host></Host>放入

<Context path="" docBase="solr" reloadable="false" crosscontext="true"><Environment name="sole/home" type="java.lang.String"  value="C:\Users\bnc\Desktop\solr\home" override="true" />
</Context>

4  solr-4.8.0\example\lib\ext下库文件放在solr\server\lib

5  配置solr\server\bin下setclasspath.bat

set "JAVA_HOME=C:\Program Files\Java\jdk1.7.0_79"

6  打开solr\server\bin下点击startup.sh

7 启动验证

1)Tomcat(server)添加role和user  \solr\server\conf下  tomcat-user.xml 添加

<role rolename="solr" />

<user username="admin" password="admin" roles="solr" />

2)solr\server\webapps\solr\WEB-INF和solr\server\webapps\ROOT\WEB-INF下web.xml

<security-constraint><web-resource-collection><web-resource-name>Solr Lockdown</web-recource-name><url-pattern>/</url-pattern></web-resource-collection><auth-constraint><role-name>solr</role-name><role-name>admin</role-name></auth-constraint>
</security-constraint><login-config><auth-method>BASIC</auth-method><realm-name>Solr</realm-name></login-config>

4 solr中文分词(MMSEG4j):配置中文分词和验证中文分词

1  下载分词工具

mmseg4j-analysis-*.jar
mmseg4j-core-*.jar
mmseg4j-solr-*.jar

2 拷贝到solr\server\webapps\solr\WEB-INF\lib和solr\server\webapps\ROOT\WEB-INF\lib

3 打开 \solr\home\collection1\conf下schema.xml添加

<fieldtype name="textComplex" class="solr.TextField" positionIncrementGap="100">
<analyzer><tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="../dic"/>
</analyzer>
</fieldtype><fieldtype name="textMaxWord" class="solr.TextField" positionIncrementGap="100">
<analyzer><tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="max-word" />
</analyzer>
</fieldtype><fieldtype name="textSimple" class="solr.TextField" positionIncrementGap="100">
<analyzer><tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="simple" dicPath="../dic" />
</analyzer>
</fieldtype>

然后修改

<field name="title" type="textComplex" indexed="true" stored="true" multiValued="true"/><field name="subject" type="textComplex" indexed="true" stored="true"/><field name="description" type="textComplex" indexed="true" stored="true"/><field name="comments" type="textComplex" indexed="true" stored="true"/><field name="author" type="textComplex" indexed="true" stored="true"/><field name="keywords" type="textComplex" indexed="true" stored="true"/><field name="category" type="textComplex" indexed="true" stored="true"/><field name="resourcename" type="textComplex" indexed="true" stored="true"/><field name="url" type="textComplex" indexed="true" stored="true"/><field name="content_type" type="string" indexed="true" stored="true" multiValued="true"/><field name="last_modified" type="date" indexed="true" stored="true"/><field name="links" type="string" indexed="true" stored="true" multiValued="true"/> 

4 启动server/bin/start.bat文件

5 配置collection1 并在分析字段和字段类型配置中文分词工具textComplex即可

5 solrJ后台的使用

1) solr-4.8.0\dist\solrj-lib下所有jar文件和solr-solrj-4.8.0.jar复制到java工程lib里面。

2) SolrJ客户端插入数据

//Solr4.x版本插入数据public void add(String id,String name) throws SolrServerException, IOException{for(int i=0;i<5;i++){SolrInputDocument doc=new SolrInputDocument();doc.addField("id", id+i);doc.addField("name", "The "+name+" is "+i);server.add(doc);}}

3) SolrJ客户端更数据

//Solr4.x版本插入数据public void add(String id,String name) throws SolrServerException, IOException{for(int i=0;i<5;i++){SolrInputDocument doc=new SolrInputDocument();doc.addField("id", id+i);doc.addField("name", "The "+name+" is "+i);server.add(doc);}}

4) SolrJ客户端查询数据  

//solr查询数据public void select() throws SolrServerException{ModifiableSolrParams params = new ModifiableSolrParams();params.set("q", "id:*");params.set("start", "0");QueryResponse response = server.query(params);SolrDocumentList results = response.getResults();for (int i = 0; i < results.size(); ++i) {System.out.println(results.get(i));}}

5) SolrJ客户端删除数据

//删除solr中的视频文档:按照规则删除public void delete() throws SolrServerException, IOException{server.deleteByQuery("*:*");server.commit();}

6) 完整solrJ工具类源码

package SolrSearch;import java.io.IOException;import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.CloudSolrServer;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.params.ModifiableSolrParams;/*** Solr工具类* @author 白宁超* @version 2016年4月11日12:57:01*/
public class SolrUtils {//baseURL是固定的访问地址public static final String SOLL_URL="http://localhost:8080/solr/"; private final HttpSolrServer server;   public SolrUtils(){server=new HttpSolrServer(SOLL_URL);server.setAllowCompression(true);     //减少服务器交换的数据量//server.setSoTimeout(72000); //设置收索超时
    }//Solr4.x版本插入视频文档public void add(Vidio vidio) throws SolrServerException, IOException{SolrInputDocument doc=new SolrInputDocument();doc.addField("id", vidio.getId());doc.addField("name", vidio.getName());doc.addField("type", vidio.getType());server.add(doc);server.commit();}//Solr4.x版本插入数据public void add(String id,String name) throws SolrServerException, IOException{for(int i=0;i<100;i++){SolrInputDocument doc=new SolrInputDocument();doc.addField("id", id+i);doc.addField("name", "The "+name+" is "+i);server.add(doc);}server.commit();}//SolrCloud插入数据public static void addCloud(String id,String name) throws SolrServerException, IOException {String zkHost = "localhost:8080";String defaultCollection = "collection1";CloudSolrServer server = new CloudSolrServer(zkHost);System.out.println();for (int i = 0; i < 1000; ++i) {SolrInputDocument doc = new SolrInputDocument();doc.addField("id", "book-" + i);doc.addField("name", "The Legend of Po part " + i);server.add(doc);}server.commit();}//更新solr中的视频文档public void update(Vidio vidio) throws SolrServerException, IOException {add(vidio);}//更新solr中信息public void update(String id,String name) throws SolrServerException, IOException {add(id,name);}//删除solr中的视频文档:按照规则删除public void delete() throws SolrServerException, IOException{server.deleteByQuery("*:*");server.commit();}//删除solr中的视频文档:按照规则删除public void deleteById(Vidio vidio) throws SolrServerException, IOException{server.deleteById(vidio.getId() +"");server.commit();}//solr查询数据public void select() throws SolrServerException{ModifiableSolrParams params = new ModifiableSolrParams();params.set("q", "id:*");params.set("start", "0");QueryResponse response = server.query(params);SolrDocumentList results = response.getResults();for (int i = 0; i < results.size(); ++i) {System.out.println(results.get(i));}}}

View Code

6  本文总结

1)如何启动solr?

1、解压solr-4.8.0.zip到你想到存放的路径,比如:d:/solr

2、cmd打开命令行窗口,进入d:/solr/example目录

3、执行命令:java -jar start.jar

4、通过第三步以后,系统会启动solr自带的jetty服务器,通过http://localhost:8983/solr/便可访问solr。

2)如何创建索引?

此时solr已安装并启动,但是还没有索引,只有创建好索引,搜索才能有结果

1、cmd进入/solr/example/exampledocs目录

2、执行命令:java -jar post.jar solr.xml monitor.xml,此时你已成功提交了2个solr文档

3、执行完第二步后,我们可以通过浏览器访问:http://localhost:8983/solr/collection1/select?q=solr&wt=xml

如果你想导入更多的文档,执行命令:java -jar post.jar *.xml

3)如何更新索引?

当你重复执行命令:java -jar post.jar *.xml后,发现搜索的结果没有出现重复的数据,原因:example目录下的schema.xml中指定了列id为uniqueKey(即:唯一),所以当你重复提交数据到索引库时,id相同的数据会替换原来document中的数据。

如果你想要得到重复的数据,你可以通过修改exampledocs目录下*.xml中id值的方式实现

4)如何删除索引?

1、执行命令:java -Ddata=args -Dcommit=false -jar post.jar “<delete><id>SP2514N</id></delete>”,可以删除id为SP2514N的document

2、执行第一步后,再去搜索发现搜索结果中还有id为SP2514N的数据,难道我们第一步删除不成功吗?其实不是,因为第一步的命令中-Dcommit=false,所以第一步的删除操作没有提交到索引(index)中。

3、在没有打开新的searcher之前,第一步删除数据会一直存在于搜索结果中,所以我们可以强制打开一个新的searcher,执行命令:java -jar post.jar -

5)如何查询数据

solr通过http以get的方式进行搜索数据,如:http://localhost:8983/solr/collection1/select?q=solr&wt=xml

q:查询的关键词(此时查询的字段是solrconfig.xml中指定的默认查询字段<str name=”df”>text</str>)

fl:搜索结果返回的字段

sort:排序

wt:搜索结果返回格式

  • q=video&fl=name,id (return only name and id fields)
  • q=video&fl=name,id,score (return relevancy score as well)
  • q=video&fl=*,score (return all stored fields, as well as relevancy score)
  • q=video&sort=price desc&fl=name,id,price (add sort specification: sort by price descending)
  • q=video&wt=json (return response in JSON format)
排序

sorl提供了通过一个或多个字段进行排序的方法,使用sort参数,参数格式为“字段 排序(asc或desc)”。

  • q=video&sort=price desc
  • q=video&sort=price asc
  • q=video&sort=inStock asc, price desc

score也可以用来排序

  • q=video&sort=score desc
  • q=video&sort=inStock asc, score desc

复杂的排序

  • q=video&sort=div(popularity,add(price,1)) desc

如果没有指定sort参数,默认”score desc”进行排序,把匹配度最高的优先显示

6)如何高亮显示

有时候我们想高亮显示匹配的关键词,可以通过参数hl=true,并指定需高亮显示的字段hl.fl=name,features

…&q=video card&fl=name,id&hl=true&hl.fl=name,features

默认会把匹配的关键用“<em>”标签进行包装,如<em>手机</em>

7)如何进行门面搜索?

前面“查询数据”一栏返回的是整个文档的数据,门面搜索可以根据我们的需求返回结果,如下:

1、以下例子搜索整个文档并根据字段cat技术匹配数量:

…&q=*:*&facet=true&facet.field=cat

注意:上面的例子虽然结果中只显示10条,但返回的数量是整个文档中匹配查询条件的总的数量。

2、在例子1的基础上可以再加一个字段inStock:

…&q=*:*&facet=true&facet.field=cat&facet.field=inStock

3、solr同样可以为任意查询条件计算数量,以下例子查询关键为ipod、价格在0-99和>100

…&q=ipod&facet=true&facet.query=price:[0 TO 100]&facet.query=price:[100 TO *]

4、以下例子查询字段manufacturedate_dt在2004年到2010年:

…&q=*:*&facet=true&facet.range=manufacturedate_dt&facet.range.start=2004-01-01T00:00:00Z&facet.range.end=2010-01-01T00:00:00Z&facet.range.gap=+1YEAR

搜索界面

solr提供了搜索界面:http://localhost:8983/solr/collection1/browse

8)如何进行文本解析?

solr创建索引和进行搜索时都需要对文字进行解析,解析时需要用到分词器,中文的分词器我推荐使用mmseg4j分词器

solr核心的配置文件是schema.xml,索引库结构的定义及对每个字段采用什么分词器等都在这个文件里面进行配置

如:

<field name=”features” type=”text_en_splitting” indexed=”true” stored=”true” multiValued=”true”/>

7 本文所有文件下载

1 Apache Cat 8.0下载:https://yunpan.cn/cqGwpLKtZ6MVF  访问密码 03ba

2 solr源文件以及本文配置文件打包下载: https://yunpan.cn/cqGwCsbpfy6p8  访问密码 dcfe

3 javaJ的java源码下载: https://yunpan.cn/cqGQyevGaZ47W  访问密码 9f1a

8 参考文献:

1 五分钟solr4.8教程(搭建、运行)

2 中国使用教程,值得刚接触搜索开发人员一看

3 初级教程(介绍、安装部署、接口、中文分词)

4 孔浩视频教程Solr实战初步教程

相关文章


【文本处理】自然语言处理在现实生活中运用

【文本处理】多种贝叶斯模型构建及文本分类的实现

【文本处理】快速了解什么是自然语言处理

【文本处理】领域本体构建方法概述

转载于:https://my.oschina.net/u/3579120/blog/1539130

自己动手搭建搜索工具相关推荐

  1. 动手搭建自己的本地测试服务器

    动手搭建自测服务器,加快本地开发进度,最近自己在开发过程中有这么一个需求,在开发本地应用模块过程中,需要请求服务器测试服务器,但是服务器老出问题,于是就有自己本地搭建一个服务器的一个想法,然后配置接口 ...

  2. 自己动手搭建网站:域名和云服务器选购

    系列文章:自己动手搭建网站系列总目录 目录 1.引言 2.域名选购 3.云服务器选购 3.1选购云服务器 3.2配置安全组规则 4.参考资料 1.引言 注意:现在的网站要进行"双备案&quo ...

  3. 网盘资源搜索工具,网罗各大平台的网盘

    网盘的话题一直是热门话题,之所以热门是因为现在我们都已经离不开某网盘了是吧,不是因为他的空间比较大,而是因为我们绝大多数人都在里面存储资源和分享资源. 所以呢也衍生出了很多的第三方网盘搜索网站,他们有 ...

  4. 项目:Search_Everything(仿EveryThing的文件搜索工具)

    目录 项目总览 项目流程 项目搭建 maven项目 Database Navigator插件 类的设计和实现 Main类 resources包 app.fxml文件 init.sql文件 工具包Uti ...

  5. Everything:速度最快的文件名搜索工具(201306更新)

    [2013-06-18 更新] Everything V1.3.3.653b发布:增加64位版本:增加Home页:增加运行历史:增加最新变化. 简体中文语言包同步更新. 下载链接:百度网盘 Every ...

  6. 自己动手搭建网站系列总目录

    引言 说起来,博主从学习计算机相关知识那天开始,就对自己动手搭建网站有着一种莫名的憧憬与向往.只是那时所学实在太少,撑不起这个想法,也没想着用一些自助建站工具什么的,感觉用起来少了点意思,而且也挺麻烦 ...

  7. 动手搭建安卓开发环境

    2014已经快到尾声,2015即将来临.要问到如今最流行的手机操作系统,那就非安卓莫属了.手机作为用户粘合度最大的一种电子产品,早已成为各大厂商的兵家必争之地,所以安卓的炙手可热也是必然的.作为用户最 ...

  8. Atitit.文件搜索工具 attilax 总结

    Atitit.文件搜索工具 attilax 总结 1. 指定目录按照体积大小精确搜索1 1.1. File Seeker 4.5 版本的可以,3.5版本的不行..1 2. 按照文件内容搜索1 2.1. ...

  9. CowNew开源团队新书《自己动手写开发工具》隆重上市

    <自己动手写开发工具--基于Eclipse的工具开发> 本书系统地介绍了SWT.Draw2D.GEF.JET等与Eclipse插件开发相关的基础知识,并且以实际的开发案例来演示这些知识的实 ...

最新文章

  1. Linux操作系统下文件作用
  2. SemSegMap :基于3D点云语义信息的定位
  3. 生成打印条码_条码打印软件如何生成跳号条形码
  4. Hibernate基本原理(一)
  5. Windows Phone 7用户界面原型截图汇总
  6. android python opencv_使用Python和OpenCV自动化Android游戏
  7. Linux下如何高效删除一个几十G的文本文件的最后一行或几行
  8. 基于spring自动注入及AOP的表单二次提交验证
  9. es6 获取对象的所有值_前端开发必备 - ES6 新特性之 Set和Map数据结构
  10. 基于多模态常规技术的芒果叶片病害识别新模型
  11. 动画会震一下css,csshake.css强大的CSS3元素抖动动画库
  12. 如何用一款小工具大大加速MySQL SQL语句优化(附源码)
  13. 令人蛋疼的错误提示 0xcdcdcdcd ,0xdddddddd ,0xfeeefeee ,0xcccccccc ,0xabababab
  14. vue获取接口id_05vue2.0-vue中_接口的调用
  15. python安装哪个版本好啊_Python 的版本选择与安装细节
  16. oracle循环视频教程,玩转Oracle入门知识和实战教程---韩顺平主讲(全31集)
  17. 多项式——多项式牛顿迭代
  18. python高阶知识之——列表推导式(63)
  19. 云计算技术与应用 - 知识点
  20. Verilog状态机详述

热门文章

  1. 【PhotoScan精品教程】任务四:PhotoScan做空三+CC生成正射、三维建模综合案例
  2. 【PPT】PPT倒计时动画的制作方法 5.4.3.2.1...
  3. 软件测试—十二章测试层次
  4. springboot中对各个层的理解以及流程
  5. windows 7 iso镜像刻录到U盘后选择安装的版本
  6. ThingWorx入门
  7. 渲图买桌面CPU还是服务器cpu,做图用什么显卡好,图形渲染CPU重要还是显卡重要...
  8. 自适应OCXO漂移校正算法(翻译)
  9. 影响利率风险结构的因素_利率风险结构是什么意思 影响利率的因素
  10. 微信小程序的后台在哪里云开发控制台操作方法