SSM框架中Solr服务器的安装,配置,使用全过程
在你想要放弃的时候想想是什么让你当初坚持走到了这里
1,什么是solr服务器
Solr是一个独立的企业级搜索应用服务器,它对外提供类似于Web-service的API接口。用户可以通过http请求,向搜索引擎服务器提交一定格式的XML文件,生成索引;也可以通过Http Get操作提出查找请求,并得到XML格式的返回结果。
2,使用solr服务器有什么好处
Solr是一个高性能,采用Java开发, Solr Solr 基于Lucene的全文搜索服务器。同时对其进行了扩展,提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展并对查询性能进行了优化,并且提供了一个完善的功能管理界面,是一款非常优秀的全文搜索引擎。
3,solr服务搭建
3.1,solr环境
Solr是java开发。需要安装jdk。安装环境Linux。需要安装Tomcat。
3.2,搭建步骤
这边我用的是云服务器,和vm虚拟机一个操作(需要资料可留言)
第一步:把solr 的压缩包上传到Linux系统第二步:解压solr。
Linux命令
tar -xvf 文件名
第三步:安装Tomcat,解压缩即可。
第四步:把solr部署到Tomcat下。
复制解压缩的solr文件夹的dist文件夹里面的war包到tomcat的webapps工程目录下
第五步:启动Tomcat解压,war包会自动变成文件夹,我这里把文件夹名改成了solr,方便点
启动tomcat的命令是打开tomcat文件夹里面的bin目录
./startup.sh启动
./shutdown.sh关闭
记得开放8080端口
开放8080端口的代码是
/sbin/iptables -I INPUT -p tcp --dport 8080 -j ACCEPT
/etc/rc.d/init.d/iptables save
第六步:把解压的solr-4.10.3/example/lib/ext目录下的所有的jar包,添加到solr工程中
复制代码是
cp * /usr/local/tomcat/webapps/solr/WEB-INF/bin/
第七步:创建一个solrhome。/example/solr目录就是一个solrhome。复制此目录到/usr/local/solrhome(和解压的solr文件夹同目录) 第八步:关联solr及solrhome。需要修改solr工程的web.xml文件。第九步:启动Tomcat http://111.111.111.111:8080/solr/ 和windows下的配置完全一样。步骤需要注意的地方:删除tomcat工程下面的war包需要关闭tomcat 配置文件需要把注释去掉 不知道自己的solrhome所在的目录的话,进去目录输入命令pwd查看路径 访问solr工程显示404是自己配置哪里出问题了,重新检查配置 爱你们
3.3,配置业务域
schema.xml中定义(这是我当前的项目所需要的域,自己分析自己需要把哪些放到solr中供搜索) 1、商品Id 2、商品标题 3、商品卖点 4、商品价格 5、商品图片 6、分类名称
创建对应的业务域。需要制定中文分析器(这边搜索的都是中文,需要配置中文分析器)。
创建步骤:第一步:把中文分析器添加到工程中。1、把IKAnalyzer2012FF_u1.jar添加到solr工程的lib目录下
2、把扩展词典、配置文件放到solr工程的WEB-INF/classes目录下第二步:配置一个FieldType,制定使用IKAnalyzer 修改schema.xml文件 修改Solr的schema.xml文件,添加FieldType:
<fieldType name="text_ik" class="solr.TextField">
<analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
第三步:配置业务域,type制定使用自定义的FieldType。设置业务系统Field
<field name="item_title" type="text_ik" indexed="true" stored="true"/>
<field name="item_sell_point" type="text_ik" indexed="true" stored="true"/>
<field name="item_price" type="long" indexed="true" stored="true"/>
<field name="item_image" type="string" indexed="false" stored="true" />
<field name="item_category_name" type="string" indexed="true" stored="true" />
<field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="item_title" dest="item_keywords"/>
<copyField source="item_sell_point" dest="item_keywords"/>
<copyField source="item_category_name" dest="item_keywords"/>
xml文件的路径图片中标出了,在solrhome里面
第四步:重启tomcat
4,搜索工程搭建
要实现搜索功能,需要搭建solr服务、搜索服务工程、搜索系统
4.1,搜索服务工程搭建
e3-search(聚合工程pom) --e3-search-interface(jar) --e3-search-Service(war) e3-search-web(war)
5,使用solrJ管理索引库
5.1,添加文档
第一步:把solrJ的jar包添加到工程中。第二步:创建一个SolrServer,使用HttpSolrServer创建对象。第三步:创建一个文档对象SolrInputDocument对象。第四步:向文档中添加域。必须有id域,域的名称必须在schema.xml中定义。第五步:把文档添加到索引库中。第六步:提交。
@Test
public void addDocument() throws Exception {
//创建一个SolrServer对象,创建一个连接。参数solr服务的url
SolrServer solrServer = new HttpSolrServer("http://111.111.111.111:8080/solr/collection1");
//创建一个文档对象SolrInputDocument
SolrInputDocument document = new SolrInputDocument();
//向文档对象中添加域。文档中必须包含一个id域,所有的域的名称必须在schema.xml中定义。
document.addField("id", "doc01");
document.addField("item_title", "测试商品01");
document.addField("item_price", 1000);
//把文档写入索引库
solrServer.add(document);
//提交
solrServer.commit();
}
5.2,删除文档
@Test
public void deleteDocument() throws Exception {
SolrServer solrServer = new HttpSolrServer("http://111.111.111.111:8080/solr/collection1");
//删除文档
//solrServer.deleteById("doc01");//根据id删除
solrServer.deleteByQuery("id:doc01");//根据查询删除
//提交
solrServer.commit();
}
5.3,查询索引库
查询步骤:第一步:创建一个SolrServer对象 第二步:创建一个SolrQuery对象。第三步:向SolrQuery中添加查询条件、过滤条件。。。第四步:执行查询。得到一个Response对象。第五步:取查询结果。第六步:遍历结果并打印。
5.3.1,简单查询
@Test
public void queryIndex() throws Exception {
//创建一个SolrServer对象。
SolrServer solrServer = new HttpSolrServer("http://111.111.111.111:8080/solr/collection1");
//创建一个SolrQuery对象。
SolrQuery query = new SolrQuery();
//设置查询条件。
//query.setQuery("*:*");
query.set("q", "*:*");
//执行查询,QueryResponse对象。
QueryResponse queryResponse = solrServer.query(query);
//取文档列表。取查询结果的总记录数
SolrDocumentList solrDocumentList = queryResponse.getResults();
System.out.println("查询结果总记录数:" + solrDocumentList.getNumFound());
//遍历文档列表,从取域的内容。
for (SolrDocument solrDocument : solrDocumentList) {
System.out.println(solrDocument.get("id"));
System.out.println(solrDocument.get("item_title"));
System.out.println(solrDocument.get("item_sell_point"));
System.out.println(solrDocument.get("item_price"));
System.out.println(solrDocument.get("item_image"));
System.out.println(solrDocument.get("item_category_name"));
}
}
5.3.1,带高亮显示
@Test
public void queryIndexFuza() throws Exception {
SolrServer solrServer = new HttpSolrServer("http://111.111.111.111:8080/solr/collection1");
//创建一个查询对象
SolrQuery query = new SolrQuery();
//查询条件
query.setQuery("手机");
query.setStart(0);
query.setRows(20);
query.set("df", "item_title");
query.setHighlight(true);
query.addHighlightField("item_title");
query.setHighlightSimplePre("<em>");
query.setHighlightSimplePost("</em>");
//执行查询
QueryResponse queryResponse = solrServer.query(query);
//取文档列表。取查询结果的总记录数
SolrDocumentList solrDocumentList = queryResponse.getResults();
System.out.println("查询结果总记录数:" + solrDocumentList.getNumFound());
//遍历文档列表,从取域的内容。
Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
for (SolrDocument solrDocument : solrDocumentList) {
System.out.println(solrDocument.get("id"));
//取高亮显示
List<String> list = highlighting.get(solrDocument.get("id")).get("item_title");
String title = "";
if (list !=null && list.size() > 0 ) {
title = list.get(0);
} else {
title = (String) solrDocument.get("item_title");
}
System.out.println(title);
System.out.println(solrDocument.get("item_sell_point"));
System.out.println(solrDocument.get("item_price"));
System.out.println(solrDocument.get("item_image"));
System.out.println(solrDocument.get("item_category_name"));
}
}
6,把商品数据导入到索引库中
6.1,分析dao层
创建sql语句 创建表对应的pojo 创建mapper映射文件(接口和xml)
6.2,分析service层
创建接口 实现接口 书写代码
@Autowired
private ItemMapper itemMapper;
@Autowired
private SolrServer solrServer;
@Override
public E3Result importAllItems() {
try {
//查询商品列表
List<SearchItem> itemList = itemMapper.getItemList();
//遍历商品列表
for (SearchItem searchItem : itemList) {
//创建文档对象
SolrInputDocument document = new SolrInputDocument();
//向文档对象中添加域
document.addField("id", searchItem.getId());
document.addField("item_title", searchItem.getTitle());
document.addField("item_sell_point", searchItem.getSell_point());
document.addField("item_price", searchItem.getPrice());
document.addField("item_image", searchItem.getImage());
document.addField("item_category_name", searchItem.getCatagory_name());
//把文档对象写入索引库
solrServer.add(document);
}
//提交
solrServer.commit();
//返回导入成功
return E3Result.ok();
} catch (Exception e) {
e.printStackTrace();
return E3Result.build(500, "数据导入时发生异常");
}
}
需要在spring中配置ttpSolrServer类(配置子类,service引入父类SolrServer )
6.3,发布服务,用dubbo协议暴露端口
<!-- 使用dubbo发布服务 -->
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="e3-search" />
<dubbo:registry protocol="zookeeper" address="111.111.111.111:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20882" />
<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="cn.e3mall.search.service.SearchItemService" ref="searchItemServiceImpl" timeout="600000"/>
6.4,分析controller层
直接调用就完事,我这是异步请求
@Autowired
private SearchItemService searchItemService;
@RequestMapping("/index/item/import")
@ResponseBody
public E3Result importItemList() {
E3Result importAllItems = searchItemService.importAllItems();
return importAllItems;
}
注意,解决mapper映射文件不存在的异常,我在上一篇博客发了,需要请查看
7,搜索功能实现
7.1,dao层分析
public SearchResult search(SolrQuery query) throws Exception{
//根据query查询索引库
QueryResponse query2 = solrServer.query(query);
//取查询结果
SolrDocumentList results = query2.getResults();
//取查询结果总记录数
long numFound = results.getNumFound();
SearchResult result=new SearchResult();
result.setRecordCount(numFound);;
List<SearchItem> list=new ArrayList<>();
//取商品列表,需要取高亮显示
Map<String, Map<String, List<String>>> highlighting = query2.getHighlighting();
for (SolrDocument solrDocument : results) {
SearchItem search=new SearchItem();
search.setId((String) solrDocument.get("id"));
search.setCatagory_name((String) solrDocument.get("item_catagory_name"));
search.setImage((String) solrDocument.get("item_image"));
search.setPrice(solrDocument.get("item_price").toString());
search.setSell_point((String) solrDocument.get("item_sell_point"));
//高亮设置显示
List<String> list2 = highlighting.get(solrDocument.get("id")).get("item_title");
String title="";
if(list2!=null&&list2.size()>0) {
title=list2.get(0);
}else {
title=(String) solrDocument.get("item_title");
}
search.setTitle(title);
list.add(search);
}
result.setItemList(list);
return result;
}
7.2,service层分析
public SearchResult search(String keyword, int page, int rows) throws Exception {
//创建一个solrQuery对象
SolrQuery query=new SolrQuery();
//设置查询条件
query.setQuery(keyword);
System.out.println("------------------"+keyword);
//设置分页条件
if(page<=0) {
page=1;
}
query.setStart((page-1)*rows);
query.setRows(rows);
//设置默认搜索域
query.set("df", "item_title");
//开启高亮显示
query.setHighlight(true);
query.addHighlightField("item_title");//设置高亮显示的域
query.setHighlightSimplePre("<em style=\"color=red\">");//设置高亮标签前缀
query.setHighlightSimplePost("</em>");//设置高亮标签后缀
//调用dao执行查询
SearchResult search = searchDao.search(query);
//计算总页数
Long recordCount = search.getRecordCount();
System.out.println(recordCount+"------------");
search.setTotalPages((int) Math.ceil(recordCount/rows));
//返回结果
return search;
}
7.2,controller层分析
@RequestMapping("/search")
public String searchItemList(String keyword,@RequestParam(defaultValue = "1")Integer page
,Model model) throws Exception{
//get请求转码
keyword=new String(keyword.getBytes("iso-8859-1"),"UTF-8");
SearchResult search = searchService.search(keyword, page, rows);
//把结果传递给页面
model.addAttribute("query", keyword);
System.out.println(keyword);
model.addAttribute("totalPages", search.getTotalPages());
System.out.println(search.getTotalPages());
model.addAttribute("page", page);
System.out.println(page);
model.addAttribute("recourdCount", search.getRecordCount());
System.out.println(search.getRecordCount());
model.addAttribute("itemList", search.getItemList());
System.out.println(search.getItemList());
return "search";
}
结束!
实际项目开发可查看Solr集群搭建之SolrCould以及实际项目开发中详细使用步骤这篇文章