SSM框架中Solr服务器的安装,配置,使用全过程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_15038565/article/details/102764152

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";
	}

结束!感谢支持

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_15038565/article/details/102764152