【Solr】——搜索引擎的部署及使用
最近在做毕业设计,一个电商APP,遇到搜索商品的问题,以往做的数据库模糊查询感觉不是那么的高大上,于是决定使用Solr搜索引擎,在此给同样想法的小伙伴一点借鉴,望共勉。一、Solr部署1.Solr下载部署solr通常有2中方式,一个是部署在外部的web容器中例如tomcat,另一个是使用solr内置的jetty作为web容器。因为我做的是微服务项目,感觉独立部署方便一点,所以我们这里...
最近在做毕业设计,一个电商APP,遇到搜索商品的问题,以往做的数据库模糊查询感觉不是那么的高大上,于是决定使用Solr搜索引擎,在此给同样想法的小伙伴一点借鉴,望共勉。
一、Solr部署
1.Solr下载
部署solr通常有2中方式,一个是部署在外部的web容器中例如tomcat,另一个是使用solr内置的jetty作为web容器。因为我做的是微服务项目,感觉独立部署方便一点,所以我们这里采用内置的jetty作为web容器的部署方式。
在Solr官网下载适合的版本,windows下选择后缀为.zip的安装包,博主选择的是5.2.1,下载之后找到合适的位置解压
2.Sorl启动
在cmd窗口进入solr的解压目录下的bin文件夹点击下列命令:
注意窗口不要关闭,否则会断开服务器
在浏览器访问solr的管理界面 ,出现下面界面表示启动成功
3. 创建core
方法一:命令行创建
bin目录下cmd窗口执行,如下命令:
方法二:solr管理页面 创建
1.在下图目录中新建new_core
2.上图中的configsets文件中存放的是基本的配置文件,把configsets中的basic_configs下的conf拷贝到new_core中,然后新建文件夹data,作为索引数据的存放文件
3.在solr管理页面中点击core admin 下的 add core,修改name 和instanceDir为new_core,然后点击add core
4.创建完成
刷新界面,可以看到我们创建的core
二、Solr使用
导入数据
solr中负责导入数据的模块叫做DataImportHandler,它有多种实现方式
数据库导入
这里做示范,我们选择一个比较简单的表结构进行数据导入
solr支持多中形式的数据导入,其中最常用的就是从数据库导入数据
我们可以从solr自带的/example/example-DIH/solr/db/conf中找到从数据库导入数据的相关配置作为参考,然后修改coreTest1内的配置1.修改solrconfig.xml
在最后其后添加如下配置
<requestHandler name="/dataimport" class="solr.DataImportHandler"> <lst name="defaults"> <str name="config">db-data-config.xml</str> </lst> </requestHandler>
2.从example中拷贝db-data-config.xml到coreTest1,并根据数据库的使用情况进行修改,我这里使用的是mysql
<dataConfig> <dataSource driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/shopsystem" user="root" password="root" /> <document> <entity name="item" query="select * from user"> <field column="user_id" name="id" /> <field column="user_sex" name="user_sex" /> <field column="user_name" name="user_name" /> </entity> </document> </dataConfig>
这里有个坑,column对应数据库的列名,name为显示的列名,对应下面schema.xml文件中的name,这里必须要有一个name为id
3.将mysql的数据库连接jar拷贝到solr根目录的dist文件中,然后修改solrconfig.xml,加载这个jar包
<lib dir="${solr.install.dir:../../../..}/dist/" regex=".*\.jar" />
4.修改managed-schema为schema.xml,如果已经存在则忽略,根据db-data-config.xml中的配置的从数据库导入的字段进行修改.
<field name="user_sex" type="string" indexed="true" stored="true" required="true" multiValued="false" /> <field name="user_name" type="string" indexed="true" stored="true" required="true" multiValued="false" />
这里不需要再设置id列,因为这个文件中已经默认存在,这也是第2步中注意事项所说的
5.在core admin选项中 选择刚刚修改的coreTest1,然后点击reload按钮,加载刚刚上面修改的配置
6.开始导入数据,选择刚刚修改的coreTest1下面的DataImport选项,然后点击execute按钮
7.如果还是没成功可以去左侧导航栏的Logging查看那个地方有问题,一步步总会成功的
solr管理界面导入
服务器导入
数据库导入个人感觉适合查询数据集中的情况,我要查询的数据在多个表中, 而且数据会插入不同的core中,所以我选择了在服务端随着数据的改变通过代码对数据进行更新。
下面是一个导入数据的工具类,直接调用即可,读者可根据注解自行修改
@Service public class SolrService<T> { // 指定solr服务器的地址 private final static String SOLR_URL = "http://localhost:8983/solr/"; private String solrCore = "shopstem";// 指定的存储数据的collection /** * 创建SolrServer对象 * * 该对象有两个可以使用,都是线程安全的 1、CommonsHttpSolrServer:启动web服务器使用的,通过http请求的 2、 * EmbeddedSolrServer:内嵌式的,导入solr的jar包就可以使用了 3、solr * 4.0之后好像添加了不少东西,其中CommonsHttpSolrServer这个类改名为HttpSolrClient * * @return */ public HttpSolrClient createSolrServer() { HttpSolrClient solr = null; solr = new HttpSolrClient(SOLR_URL); solr.setConnectionTimeout(100); solr.setDefaultMaxConnectionsPerHost(100); solr.setMaxTotalConnections(100); return solr; } public void addBeansBatch(List<T> list) throws IOException, SolrServerException { HttpSolrClient solr = new HttpSolrClient(SOLR_URL + solrCore); solr.addBeans(list); solr.commit(); solr.close(); } public void addBean(T t) throws IOException, SolrServerException { HttpSolrClient solr = new HttpSolrClient(SOLR_URL + solrCore); solr.addBean(t); solr.commit(); solr.close(); } /** * 往索引库添加文档 * * @throws IOException * @throws SolrServerException */ public void addDoc() throws SolrServerException, IOException { // 构造一篇文档 SolrInputDocument document = new SolrInputDocument(); // 往doc中添加字段,在客户端这边添加的字段必须在服务端中有过定义 document.addField("id", "4"); document.addField("goods_name", "LG 55LG63CJ-CA 4K液晶"); document.addField("goods_price", "1000"); document.addField("attr_name", "黄色,自由组合"); document.addField("type_name", "超薄电视"); // 获得一个solr服务端的请求,去提交 ,选择具体的某一个solr core HttpSolrClient solr = new HttpSolrClient(SOLR_URL + solrCore); solr.add(document); solr.commit(); solr.close(); } /** * 根据id从索引库删除文档 */ public void deleteDocumentById(String id) throws Exception { // 选择具体的某一个solr core HttpSolrClient server = new HttpSolrClient(SOLR_URL + solrCore); // 删除文档 server.deleteById(id); // 删除所有的索引 //server.deleteByQuery("*:*"); // 提交修改 server.commit(); server.close(); } /** * 查询 * * @throws Exception */ public List<Goods> querySolr(String search) throws Exception { HttpSolrClient solrServer = new HttpSolrClient(SOLR_URL + solrCore); SolrQuery query = new SolrQuery(); // 下面设置solr查询参数 query.set("q", search);// 参数q 查询所有 //query.set("q","*长虹*");//相关查询,比如某条数据某个字段含有周、星、驰三个字 将会查询出来 // ,这个作用适用于联想查询 // 参数fq, 给query增加过滤查询条件 // query.addFilterQuery("id:[0 TO 9]");//id为0-9 // 给query增加布尔过滤条件 // query.addFilterQuery("description:演员"); //description字段中含有“演员”两字的数据 // 参数df,给query设置默认搜索域 // query.set("df", "name"); //query.setQuery("name:*"); //query.setQuery("goods_name:"+search+" OR goods_price:"+search+" OR type_name:"+search+"" );//name // 包含zhangsan或者123 // query.setQuery("name:*zhangsan* AND description:*zhangsan*" );// // name包含且 // 分组查询 //query.setFacet(true); //query.addFacetField("name", "description");// 两个域有各自独立的结果 /* * FacetComponet有两种排序选择,分别是count和index, * count是按每个词出现的次数,index是按词的字典顺序。如果查询参数不指定facet.sort,solr默认是按count排序。 */ query.setFacetSort(FacetParams.FACET_SORT_COUNT); /* query.setFacetLimit(101); */// 设置返回结果条数 ,-1表示返回所有,默认值为100 /* query.setParam(FacetParams.FACET_OFFSET, "100"); */// 开始条数,偏移量,它与facet.limit配合使用可以达到分页的效果 query.setFacetMinCount(1);// 设置 限制 count的最小返回值,默认为0 query.setFacetMissing(false);// 不统计null的值 /* query.setFacetPrefix("test");//设置前缀 */ // 参数sort,设置返回结果的排序规则 // query.addSort("id",SolrQuery.ORDER.asc); // query.addSort("name", SolrQuery.ORDER.desc); // 设置分页参数 // query.setStart(0); // query.setRows(10);//每一页多少值 // 参数hl,设置高亮 query.setHighlight(true); // 设置高亮的字段 query.addHighlightField("goods_name"); // 设置高亮的样式 query.setHighlightSimplePre("<font color='red'>"); query.setHighlightSimplePost("</font>"); // 获取查询结果 QueryResponse response = solrServer.query(query); // 两种结果获取:得到文档集合或者实体对象 // 获取高亮数据结果 // Map<String, Map<String, List<String>>> map = // response.getHighlighting(); // 得到FacetField结果 System.out.println(response.getFacetFields()); // 获取高亮数据结果 System.out.println("高亮数据结果" + response.getHighlighting()); // 查询得到文档的集合 SolrDocumentList solrDocumentList = response.getResults(); System.out.println("通过文档集合获取查询文档数量:" + solrDocumentList.getNumFound()); // 遍历列表 List<Goods> list = new ArrayList<Goods>(); for (SolrDocument doc : solrDocumentList) { Goods goods = new Goods(); goods.setGoods_id(Integer.parseInt(doc.get("goods_id").toString().substring(doc.get("goods_id").toString().indexOf("[")+1,doc.get("goods_id").toString().length()-1))); //goodsdetail.setGoods_name( doc.get("goods_name").toString().substring(doc.get("goods_name").toString().indexOf("[")+1,doc.get("goods_name").toString().length()-1)); //goodsdetail.setType_name( doc.get("type_name").toString().substring(doc.get("type_name").toString().indexOf("[")+1,doc.get("type_name").toString().length()-1)); //goodsdetail.setAttr_name(doc.get("attr_name").toString().substring(doc.get("attr_name").toString().indexOf("[")+1,doc.get("attr_name").toString().length()-1)); System.out.println(goods.toString()); list.add(goods); } // 得到实体对象 // List<GoodsDetail> tmpLists = response.getBeans(GoodsDetail.class); // if (tmpLists != null && tmpLists.size() > 0) { // System.out.println("实体对象赋值内容:"); // for (Person per : tmpLists) { // System.out.println(per.toString()); // } // } // System.out.println(tmpLists); return list; } public static void main(String[] args) throws Exception { SolrService solr = new SolrService(); // solr.createSolrServer(); solr.addDoc(); //solr.addPersonIndex(); //solr.addPersonBatch(); //solr.deleteDocumentById("149d9e7b-064f-4977-bc21-a9c0c61fbf32"); //solr.querySolr("超薄电视"); } }
下面是我放一下我所实现的web端及APP端的搜索功能图
更多推荐
所有评论(0)