前言:数据库(Mysql等)搜索都是很容易实现的,执行sql语句就可以实现,得到查询结果,我们知道其原因是数据存储的有规律的 ,有行有列,数据格式,数据长度都是固定的。我们称为结构化数据。
在自己学习Solr之后,记录一篇学习过程---共同进步!
一:主要了解一下luncen基本概念,为slor搭建使用做基础。
1.数据分类
结构化数据: ---指具有固定格式或有限长度的数据,如数据库。
非结构化数据:---指不定长或无固定格式的数据,如邮件,word文档等磁盘上的文件
2.非结构化数据查询方法
1.顺序扫描法 如同windows的文件搜索,但是量多的话,要很久,而且只能搜索文件名称,而文件内容不能判断。
2.全文检索(Full-text Search):将非结构化的数据一部分信息提取出来,重新组织,使其有结构,所以难点怎么创建这个组织。
这部分从非结构化数据中提取出的然后重新组织的信息,我们称之索引。
例子:字典功能,字典的拼音表和部首检字表就相当于字典的索引,对每一个字的解释是非结构化的,如果字典没有音节表和部首检字表,在茫茫辞海中找一个字只能顺序扫描。于是将读音拿出来按一定的顺序排列,每一项读音都指向此字的详细解释的页数。我们搜索时按结构化的拼音搜到读音,然后按其指向的页数,便可找到我们的非结构化数据——也即对字的解释。
3.如何实现全文检索
此处我们介绍lucene实现全文检索,但是slor将lucene做了封装,使我们使用更方便,他俩的关系,就像servlet和spring框架的使用本来许多自己做的事,都交给配置,使用方便,为了学习了解slor,还是了解一下lucene。
4.全文检索的应用场景
首先肯定是数据结构不固定的数据,且数据量大的,我们使用全文检索功能,比如:百度,Google搜索引擎,论坛站内搜索,电商站内搜索等。
5.Lucene实现全文检索的流程
讲一讲基本的流程和概念,为学习solr做一些基础。
lucene(创建索引-----查询索引)创建需要花大时间。
流程图如下:
概念:Field域的属性
是否分析:是否对域的内容进行分词处理。前提是我们要对域的内容进行查询。
是否索引:将Field分析后的词或整个Field值进行索引,只有索引方可搜索到。
是否存储:将Field值存储在文档中,存储在文档中的Field才可以从Document中获取
Field类:StringField,LongField,StoredField,TextField。
二:使用slor完成电商站内搜索功能--并高亮显示关键字。
1. Solr安装及配置
从Solr官方网站(http://lucene.apache.org/solr/ )下载。Linux下需要下载lucene-4.10.3.tgz,windows下需要下载lucene-4.10.3.zip。 他给我们写好了一个程序,在解压的文件结构-example-webapps-slor.war将文件放在自己的tomcat的webapp中,手动解压,做些一些配置,浏览器输入http://localhost:8080/solr看到管理界面。
讲一下解压的文件结构:
bin:solr的运行脚本 基本不用
contrib:solr的一些贡献软件/插件,用于增强solr的功能
dist:该目录包含build过程中产生的war和jar文件,以及相关的依赖文件。
docs:solr的API文档
example:solr工程的例子目录
l example/solr:
该目录是一个包含了默认配置信息的Solr的Core目录。
2 example/multicore:
该目录包含了在Solr的multicore中设置的多个Core目录。
3 example/webapps:
该目录中包括一个solr.war,该war可作为solr的运行实例工程。
licenses:solr相关的一些许可信息
运行环境:
Solr:Solr4.10.3
Jdk:jdk1.8.0_161
Tomcat:apache-tomcat-8.0.16
2.Solr整合tomcat
保证Solr管理界面的运行。
1.自己在创建一个Solr home目录,SolrHome是Solr运行的主目录,目录中包括了运行Solr实例所有的配置文件和数据文件,Solr实例就是SolrCore,一个SolrHome可以包括多个SolrCore(Solr实例),每个SolrCore提供单独的搜索和索引服务。
2.将solr-4.10.3\example\solr下文件复制到Solr home目录下。
SolrCore----就是 solr-4.10.3\example\solr下有个collection1,就相当于我们mysql的一个database。
而Solr home就相当于mysql这个外框架。
3.安装tomcat F:\system-study\solr\example\apache-tomcat-8.0.30
4.把solr的war包复制到tomcat 的webapp目录下。 war包在solr-4.10.3-example-webapps-slor.war下
5.solr.war解压,删除war原包,保证我等会配置的slor是唯一的,不然每次tomcat重启都会覆盖上一个slor解压后的文件。
6.把\solr-4.10.3\example\lib\ext目录下的所有的jar包添加到solr工程中,是solr的jar包,我们放在下面的lib下
7.配置solrHome和solrCore
让系统知道我的家和使用家中哪个实例。
1)创建一个solrhome(存放solr所有配置文件的一个文件夹)。\solr-4.10.3\example\solr目录就是一个标准的solrhome。
2)把\solr-4.10.3\example\solr文件夹复制到D:\temp\0108路径下,改名为solrhome,改名不是必须的,是为了便于理解。
3)在solrhome下有一个文件夹叫做collection1这就是一个solrcore。就是一个solr的实例。一个solrcore相当于mysql中一个数据库。Solrcore之间是相互隔离。
i. 在solrcore(controller1)中有一个文件夹叫做conf,包含了索引solr实例的配置信息。
8.告诉家的位置
在tomcat-webapps找到solr 在里面的web.xml中配置 添加
9.启动tomcat apache-tomcat-8.0.30\bin---startup.bat 在linux中startup.sh
10.访问http://localhost:8080/solr/
出现:
打五角心的就是我们要连接的solrCore 也就是我们对应mysql的database.一开始就一个controller1,我们可以在\solrhome中复制controller1,改名controller2,并双击controller2修改core.properties ----- name=collection2 重启tomcat.
在重登,我们会看到2个选择
三。Solr后台管理----基础使用
1.
登入controller1,
Analysis分词器,后面介绍添加中文分词器
Datainport 批量导入数据--从关系数据库将数据导入 到Solr索引库中--后面介绍。现在点击会提示,无插件
Docunments--这边就是我们增删改一个数据的操作地方----主义改就是先执行删,后再添加的过程与mysql的不同之处。
增 点击Query查询删
改点击Query查询
Query 就是查询的使用。
基本一开始了解使用上面4个。
2.安装中文分词器
第一步:把IKAnalyzer2012FF_u1.jar添加到solr/WEB-INF/lib目录下。
第二步:复制IKAnalyzer的配置文件和自定义词典和停用词词典到solr的classpath下。
第三步:在schema.xml中添加一个自定义的fieldType,使用中文分析器。
<!-- IKAnalyzer--> <fieldType name="text_ik" class="solr.TextField"> <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/> </fieldType>
第四步:定义field,指定field的type属性为text_ik
<!--IKAnalyzer Field--> <field name="title_ik" type="text_ik" indexed="true" stored="true" /> <field name="content_ik" type="text_ik" indexed="true" stored="false" multiValued="true"/>
第四步:重启tomcat
第五步:测试
四。批量导入数据
此处我们将mysql中的结构化数据导入到solr中。
第一步:把dataimport插件依赖的jar包添加到solrcore(collection1\lib)中
还需要mysql的数据库驱动。
第二步:配置solrconfig.xml文件,添加一个requestHandler。
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler"> <lst name="defaults"> <str name="config">data-config.xml</str> </lst> </requestHandler>
第三步:创建一个data-config.xml,保存到collection1\conf\目录下 没有就自己建。配置数据库的连接,和database及那个表的数据要导入 <field column="name" name="product_name"/> name 是数据库字段,product_name是solr的域,我们要自己配。
<?xml version="1.0" encoding="UTF-8" ?> <dataConfig> <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/lucene" user="root" password="root"/> <document> <entity name="product" query="SELECT pid,name,catalog_name,price,description,picture FROM products "> <field column="pid" name="id"/> <field column="name" name="product_name"/> <field column="catalog_name" name="product_catalog_name"/> <field column="price" name="product_price"/> <field column="description" name="product_description"/> <field column="picture" name="product_picture"/> </entity> </document> </dataConfig>
第四步:配域
schema.xml,在SolrCore的conf目录下,它是Solr数据表配置文件,它定义了加入索引的数据的数据类型的。
<!--product-->
<field name="product_name" type="text_ik" indexed="true" stored="true"/>
<field name="product_price" type="float" indexed="true" stored="true"/>
<field name="product_description" type="text_ik" indexed="true" stored="false" />
<field name="product_picture" type="string" indexed="false" stored="true" />
<field name="product_catalog_name" type="string" indexed="true" stored="true" />
<field name="product_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="product_name" dest="product_keywords"/>
<copyField source="product_description" dest="product_keywords"/>
第五步:重启测试
到入数据前会先清空索引库,然后再导入。
点击execute.等完成了到Query中查询。
Query中有关键字查,带过滤查,分页查,高亮查,排序查等。
到此基本solr搭建完成。
五 我们开始写一个实例(电商搜索信息)
我们要知道solr是怎么和java交互的 主要SolrJ 入下图关系
工程搭建
创建一个web工程导入jar包
1、springmvc的相关jar包
2、solrJ的jar包
3、Example\lib\ext下的jar包
步骤一:在web。xml中配置前端解析器,post乱码
步骤二:在springmvc.xml中<!-- 配置视图解析器 --> <!-- SolrServer的配置 -->
步骤三:写model层,Dao层,Daoimpl层,Service层,ServiceImpl层,Controller层
model:
// 商品编号 private String pid; // 商品名称 private String name; // 商品分类名称 private String catalog_name; // 价格 private float price; // 商品描述 private String description; // 图片名称 private String picture;
Daoimpl是最主要的代码
@Autowired private SolrServer solrServer; //// 通过上面四个条件查询对象商品结果集 public List<ProductModel> selectProductModelListByQuery(String queryString, String catalog_name, String price,String sort) throws Exception { // 查询 关键词 过滤条件 // 价格排序 分页 开始行 每页数 高亮 默认域 只查询指定域 SolrQuery solrQuery = new SolrQuery(); // 关键词 solrQuery.setQuery(queryString); // 过滤条件 if(null != catalog_name && !"".equals(catalog_name)){ solrQuery.set("fq", "product_catalog_name:" + catalog_name); } if(null != price && !"".equals(price)){ //0-9 50-* String[] p = price.split("-"); solrQuery.set("fq", "product_price:[" + p[0] + " TO " + p[1] + "]"); } // 价格排序 if("1".equals(sort)){ solrQuery.addSort("product_price", ORDER.desc); }else{ solrQuery.addSort("product_price", ORDER.asc); } // 分页 solrQuery.setStart(0); solrQuery.setRows(20); // 默认域 solrQuery.set("df", "product_keywords"); // 只查询指定域 solrQuery.set("fl", "id,product_name,product_price,product_picture"); // 高亮 // 打开开关 solrQuery.setHighlight(true); // 指定高亮域 solrQuery.addHighlightField("product_name"); // 前缀 solrQuery.setHighlightSimplePre("<span style='color:red'>"); solrQuery.setHighlightSimplePost("</span>"); // 后缀 // 执行查询 QueryResponse response = solrServer.query(solrQuery); // 文档结果集 SolrDocumentList docs = response.getResults(); Map<String, Map<String, List<String>>> highlighting = response.getHighlighting(); // Map K id V Map // Map K 域名 V List // List list.get(0) // 总条数 //long numFound = docs.getNumFound(); List<ProductModel> productModels = new ArrayList<ProductModel>(); for (SolrDocument doc : docs) { ProductModel productModel = new ProductModel(); productModel.setPid((String) doc.get("id")); productModel.setPrice((Float) doc.get("product_price")); productModel.setPicture((String) doc.get("product_picture")); //1 productModel.setName((String) doc.get("product_name")); /* 2 Map<String, List<String>> map = highlighting.get((String) doc.get("id")); Map<String, List<String>> map = highlighting.get((String) doc.get("id")); List<String> list =map.get("product_name"); String listname=list.get(0); */ Map<String, List<String>> map = highlighting.get((String) doc.get("id")); List<String> list = map.get("product_name"); //判断高亮必须不为空 //不判断的话会报空指针 报nullpoint 解决if(null != list && list.size() > 0)判断 if(null != list && list.size() > 0){ String name = list.get(0); productModel.setName(name); } productModels.add(productModel); } return productModels; }
返回一个model的list用户前段展示。
Service层:
@Autowired private ProductDao jdDao; //// 通过上面四个条件查询对象商品结果集 public List<ProductModel> selectProductModelListByQuery(String queryString, String catalog_name, String price,String sort) throws Exception { return jdDao.selectProductModelListByQuery(queryString, catalog_name, price, sort); }
Controller层
@Autowired private ProductService jdService; //商品列表 @RequestMapping(value = "list.action") public String list(String queryString,String catalog_name,String price, String sort,Model model) throws Exception{ //通过上面四个条件查询对象商品结果集 List<ProductModel> productModels = jdService.selectProductModelListByQuery(queryString, catalog_name, price, sort); model.addAttribute("productModels", productModels); model.addAttribute("queryString", queryString); model.addAttribute("catalog_name", catalog_name); model.addAttribute("price", price); model.addAttribute("sort", sort); return "product_list";
项目部署完成后,我们启动tomcat,由于solr项目已经占了8080端口,我们双击自己eclipse-server-tomcat
修改成8081对应的三个都要改。
现在启动项目浏览器输入:localhost:8081/solrsearch/list.action
输入台灯:
项目基本完成:下面给上源码。
项目地址:https://download.csdn.net/download/wu6cfp38/10364573
包括,配置完好的solr(中文分析器)+我配置的SolrHome+mysql的数据库+javaweb程序
注意:我给的solr是配好的,可以自己根据上面的自己配一个完好的solr.
1.对Lucene的简单描述: