安装参考网址:https://www.cnblogs.com/zhuxiaojie/p/5764680.html https://www.cnblogs.com/zhuxiaojie/p/5764680.html
| 至于为什么要用solr5.5,因为最新的6.10,没有中文的分词器支持,这里使用的是ik分词器,刚好支持到5.5 |
|---|
| ik分词器下载地址 :https://github.com/EugenePig/ik-analyzer-solr5 , 下载完之后使用maven命令, mvn package 即可生成jar文件,或者下载我编译好的 http://pan.baidu.com/s/1o7P0846 |
| solr5.5下载地址: http://apache.fayea.com/lucene/solr/5.5.2/ |
| tomcat8下载,下载地址就不说了 |
| 一:安装配置 |
| 下载完成之后,解压solr文件,解压tomcat |
| 1.1 在tomcat安装solr,并且建立solrCore |
| 1. 把solr5.5目录下的server/solr-webapp/webapp 重命名为solr,并且放置到tomcat/webapp的目录下。 |
| 2. 打开tomcat/webapp/solr/WEB-INF/web.xml |
| 3. 新建一个文件夹,不要中文目录,用来做solrHome,也就是solrCore的实例存放位置 |
| 4. 在tomcat/webapp/solr/WEB-INF/web.xml中配置solr的地址 |
![]() |
| 6. 在tomcat/webapp/solr/WEB-INF/文件夹中,建立classes目录 |
| 7. 把solr5.5/server/resource/log4j.properties 复制到上一步建立的classes目录中 |
| 8. 把solr5.5/server/lib/ext/目录下的所有jar文件复制到tomcat/webapp/solr/WEB-INF/lib/中, 这是一些日志用的jar包,不然启动报错。 |
| 把solr-5.5.5\server\solr\solr.xml复制到服务器创建的solrHome的位置, |
| 在tomcat/webapp/solr下创建lib目录,将solr-5.5.5/dist及其下文件中的jar包复制到 tomcat/webapp/solr/lib下 |
| 将solr-5.5.5/contrib/velocity/lib中的jar包复制到 tomcat/webapp/solr/lib下 |
| 9. 这个时候,可以输入http://127.0.0.1:8080/solr/admin.html来访问到solr的控制界面了。 |
![]() |
| 10. 接下来就是创建solrCore。 |
| 11. 目前solrHome目录是空的,我们创建一个空文件夹core1,这个就是我们的一个实例, 然后把solr5.5/server/solr/configsets/sample_techproducts_configs/conf/ 这个文件复制到solrHome/core1中。 |
| 13. 在solr的管理控制台界面,添加一个core1 |
![]() |
| 14. |
| 15. 这下就创建成功了一个实例core1,yge 请注意我打码的部分,需要先执行第11步操作,否则的话, 会无法创建solr core,也就是会有错误信息,这是solr的一个bug,但是至今没有修复。 |
| 1.2 安装ik中文分词器 |
| 1. 准备好ik分词器的jar包,可以自己编译,也可以下载我生成的。然后把它复制到 tomcat/webapp/solr/WEB-INF/lib里面。(千万不要复制到tomcat/lib中,这样会找不到lucene的类) |
| 2. 打开solrHome/core1/conf/managed-schema文件,在最下方,追加如下配置 |
| <analyzer type=”index” useSmart=”false” |
| class=”org.wltea.analyzer.lucene.IKAnalyzer” /> |
| <analyzer type=”query” useSmart=”true” |
| class=”org.wltea.analyzer.lucene.IKAnalyzer” /> |
| 4. 启动tomcat,即可看到text_ik分词 |
| 5. |
| 1.3 插入的文档必须与域相匹配 |
| 域,我个人也称它为字段,它在solr中有特定的含义,就类似数据库中表的列一样,规范着写入的数据, 我们先来做个例子。 |
| 可以看到,我这次插入的文档,有id,title当然,在solr中,每一条记录都必须有着一个唯一的id, 它就类似数据库中的主键,不可重复。这条记录的插入是成功的。 |
| 但是,如果我把title改成title1,这就与定义的字段不一样了,就会报错,如下图所示 |
| 可以看到,这里提示,未知的字段 title1. |
| 1.4 域的定义 field |
| 先拿出一条配置来看一下 |
| 认识一下这些属性 |
| name:域名 |
| type:域的类型,必须匹配类型,不然会报错 |
| indexed:是否要作索引 |
| stored:是否要存储 |
| required:是否必填,一般只有id才会设置 |
| multiValued:是否有多个值,如果设置为多值,里面的值就采用数组的方式来存储, 比如商品图片地址(大图,中图,小图等) |
| 1.5 配置动态域 dynamicField |
| 同样的,也先拿出一条来看看 |
| 何谓动态域呢?就是这个域的名称,是由表达式组成的,只要名称满足了这个 表达式,就可以用这个域 |
| 同样的认识一下这些属性 |
| name:域的名称,该域的名称是通过一个表达式来指定的,只要符合这这个规则,就可以使用这个域。 比如 aa_i,bb_i,13_i等等,只要满足这个表达式皆可 |
| type:对应的值类型,相应的值必须满足这个类型,不然就会报错 |
| indexed:是否要索引 |
| stored:是否要存储 |
| …其它的属性与普通的域一至 |
| 1.6 主键域 uniqueKey |
| 给出一条配置 |
| 指定一个唯一的主键,每一个文档中,都应该有一个唯一的主键,这个值不要随便改 |
| 1.7 复制域 copyField |
| 给出一条配置 |
| 说明一下相应的属性 |
| source:源域 |
| dest:目标域 |
| 复制域,将源域的内容复制到目标域中 |
| 注意:目标域必须是允许多值的,如下,nultiValued必须为true,因为可能多个源域对应一个目标域 ,所以它需要以数组来存储 |
| 1.8 域的类型 fieldType |
| 同样的给出一段配置,这段稍微有点复杂 |
| <!— in this example, we will only use synonyms at query time |
| —> |
| 给出相应属性的说明 |
| name:域的名称 |
| class:指定solr的类型 |
| analyzer:分词器的配置 |
| type: index(索引分词器),query(查询分词器) |
| tokenizer:配置分词器 |
| filter:过滤器 |
| 1.9 业务字段的实际配置 |
| 经过上面的学习,差不多了解了一些常用的配置,如今我们用field来配置实际的业务字段,有属性如下 |
| 当然,中文分词还是要用的,因为我们在前面的 1.2 章节中,已经配置了一个fieldType的中文分词, 所以我们现在一律用中文分词的域类型 |
| 主键的id就不需要配置了,默认已经把id配置为主键了,默认的配置如下 |
| 商品名称(需要分词,需要存储) |
| 商品分类(不需要分词,需要存储) |
| 商品分类名称(需要分词,需要存储) |
| 商品价格(不分词,需要存储) |
| 商品描述(需要分词,不需要存储) |
| 商品图片(不需要分词,需要存储) |
| 复制域的应用 |
| 前面我们了解了复制域,但是却不知道它的应用场景,现在我们结合实际情况来讲一下复制域 |
| 用户在搜索框搜索的时候,有可能输入的是商品名称,也有可能输入的是商品描述,也有可能输入的是一个 商品类型,那么这些值的搜索,肯定在后台是对应一个域的,那么既然如此,我们就可以把这些域合并成一个, 这样在后台只需要单独的对这一个域进行搜索就可以了 |
| 先定义一个目标域 |
| 复制域,把商品名称,商品描述,商品类型名称复制到上面的这个域中 |
| 1.10 dataimport 导入数据库数据 |
| solr默认是没有开启dataimport这个功能的,所以我们要经过一点配置来开启它 |
| 1. 首先找到solr5.5/dist/solr-dataimporthandler-5.5.2.jar,把这个文件复制到 tomcat/webapp/solr/WEB-INF/lib/下,并且找到相应数据库的驱动包,也同样放到该目录。 我这里用的是mysql的驱动包。 |
| 2. 找到solr5.5/example/example-DIH/solr/db/conf/db-data-config.xml,把其复制到 solrHome/core1/conf/下,并改名为data-config.xml. |
| 3. 找到solrHome/core1/conf/solrconfig.xml,并打开,在里面添加一段内容,如下 |
| 4. |
| 5. 打开并编辑data-config.xml,完整的配置文件如下 |
password=”密码”/> |
| 7. 重启tomcat,然后会看到如下页面 |
| 8. |
| 9. 点击蓝色的按钮,则开始导入,导入过程依据数量量的大小,需要的时间也不同,可以点击右边的 Refresh status来刷新状态,可以查看当前导入了多少条。 |
| 10. 导入成功如下 |
| 11. |
| 二:solrj的使用 |
| 代码地址 https://github.com/zxj19951029/useSolrj |
| 上面一章节已经讲完了solr的安装与配置,现在说一下使用solrj来维护solr的索引及操作, solrj就是一个java的客户端,是一个jar包的使用 |
| 首先引入MAVEN的依赖,solrj的版本号要对应solr的版本号 |
| 2.1 增加及修改 |
| 首先说明,在solr中,增加与修改都是一回事,当这个id不存在时,则是添加,当这个id存在时, 则是修改代码很好理解,直接给出 |
| private String serverUrl = “http://192.168.1.4:8080/solr/core1“; |
| /** |
| * 增加与修改 |
| * 增加与修改其实是一回事,只要id不存在,则增加,如果id存在,则是修改 |
| * @throws IOException |
| * @throws SolrServerException |
| */ |
| @Test |
| public void upadteIndex() throws SolrServerException, IOException{ |
| //已废弃的方法 |
| //HttpSolrServer server = new HttpSolrServer(“http://192.168.1.4:8080/solr/core1“); |
| //创建 |
| HttpSolrClient client = new HttpSolrClient(serverUrl); |
| SolrInputDocument doc = new SolrInputDocument(); |
| doc.addField(“id”, “zxj1”); |
| doc.addField(“product_name”, “javaWEB技术”); |
| doc.addField(“product_catalog”, “1”); |
| doc.addField(“product_catalog_name”, “书籍”); |
| doc.addField(“product_price”, “11”); |
| doc.addField(“product_description”, “这是一本好书”); |
| doc.addField(“product_picture”, “图片地址”); |
| client.add(doc); |
| client.commit(); |
| client.close(); |
| } |
| 2.2 删除索引 |
| 删除的代码也直接给出,看代码里面的注释就可以了 |
| /** |
| * 删除索引 |
| * @throws Exception |
| */ |
| @Test |
| public void deleteIndex()throws Exception{ |
| HttpSolrClient client = new HttpSolrClient(serverUrl); |
| //1.删除一个 |
| client.deleteById(“zxj1”); |
| //2.删除多个 |
| List |
| ids.add(“1”); |
| ids.add(“2”); |
| client.deleteById(ids); |
| //3.根据查询条件删除数据,这里的条件只能有一个,不能以逗号相隔 |
| client.deleteByQuery(“id:zxj1”); |
| //4.删除全部,删除不可恢复 |
| client.deleteByQuery(“:“); |
| //一定要记得提交,否则不起作用 |
| client.commit(); |
| client.close(); |
| } |
| 2.3 查询 |
| 查询稍微复杂一点,但是与solr管理界面的条件一致 |
| 这里先给出一些查询的说明,建议查看这篇文章,个人感觉还是不错的 http://blog.csdn.net/gufengshanyin/article/details/21098879 |
| q - 查询字符串,如果查询所有: (id:1) |
| fq - (filter query)过虑查询,过滤条件,基于查询出来的结果 |
| fl - 指定返回那些字段内容,用逗号或空格分隔多个。 |
| start - 分页开始 |
| rows - 分页查询数据 |
| sort - 排序,格式:sort= (score desc, price asc)表示先 “score” 降序, 再 “price” 升序,默认是相关性降序。 |
| wt - (writer type)指定输出格式,可以有 xml, json, php, phps。 |
| fl表示索引显示那些field( *表示所有field,如果想查询指定字段用逗号或空格隔开 (如:Name,SKU,ShortDescription或Name SKU ShortDescription【注:字段是严格区分大小写的】)) |
| q.op 表示q 中 查询语句的 各条件的逻辑操作 AND(与) OR(或) |
| hl 是否高亮 ,如hl=true |
| hl.fl 高亮field ,hl.fl=Name,SKU |
| hl.snippets :默认是1,这里设置为3个片段 |
| hl.simple.pre 高亮前面的格式 |
| hl.simple.post 高亮后面的格式 |
| facet 是否启动统计 |
| facet.field 统计field |
| 1. “:” 指定字段查指定值,如返回所有值: |
| 2. “?” 表示单个任意字符的通配 |
| 3. “” 表示多个任意字符的通配(不能在检索的项开始使用或者?符号) |
| 4. “~” 表示模糊检索,如检索拼写类似于”roam”的项这样写:roam~将找到形如foam和roams的单词; roam~0.8,检索返回相似度在0.8以上的记录。 |
| 5. 邻近检索,如检索相隔10个单词的”apache”和”jakarta”,”jakarta apache”~10 |
| 6. “^” 控制相关度检索,如检索jakarta apache,同时希望去让”jakarta”的相关度更加好, 那么在其后加上”^”符号和增量值,即jakarta^4 apache |
| 7. 布尔操作符AND、|| |
| 8. 布尔操作符OR、&& |
| 9. 布尔操作符NOT、!、- (排除操作符不能单独与项使用构成查询) |
| 10. “+” 存在操作符,要求符号”+”后的项必须在文档相应的域中存在 |
| 11. ( ) 用于构成子查询 |
| 12. [] 包含范围检索,如检索某时间段记录,包含头尾,date:[200707 TO 200710] |
| 给出基本的代码看一下,仅仅作为一个基本的查询,高级的查询,各位要自己结合文档 |
| package zxj.solrj; |
| import java.util.List; |
| import java.util.Map; |
| import org.apache.solr.client.solrj.SolrQuery; |
| import org.apache.solr.client.solrj.impl.HttpSolrClient; |
| import org.apache.solr.client.solrj.response.QueryResponse; |
| import org.apache.solr.common.SolrDocument; |
| import org.apache.solr.common.SolrDocumentList; |
| import org.junit.Test; |
| /** |
| * 搜索 |
| * @author Administrator |
| * |
| */ |
| public class IndexSearch { |
| private String serverUrl = “http://192.168.1.4:8080/solr/core1“; |
| @Test |
| public void search()throws Exception{ |
| HttpSolrClient client = new HttpSolrClient(serverUrl); |
| //创建查询对象 |
| SolrQuery query = new SolrQuery(); |
| //q 查询字符串,如果查询所有: |
| query.set(“q”, “product_name:小黄人”); |
| //fq 过滤条件,过滤是基于查询结果中的过滤 |
| query.set(“fq”, “product_catalog_name:幽默杂货”); |
| //sort 排序,请注意,如果一个字段没有被索引,那么它是无法排序的 |
| // query.set(“sort”, “product_price desc”); |
| //start row 分页信息,与mysql的limit的两个参数一致效果 |
| query.setStart(0); |
| query.setRows(10); |
| //fl 查询哪些结果出来,不写的话,就查询全部,所以我这里就不写了 |
| // query.set(“fl”, “”); |
| //df 默认搜索的域 |
| query.set(“df”, “product_keywords”); |
| //======高亮设置=== |
| //开启高亮 |
| query.setHighlight(true); |
| //高亮域 |
| query.addHighlightField(“product_name”); |
| //前缀 |
| query.setHighlightSimplePre(““); |
| //后缀 |
| query.setHighlightSimplePost(““); |
| //执行搜索 |
| QueryResponse queryResponse = client.query(query); |
| //搜索结果 |
| SolrDocumentList results = queryResponse.getResults(); |
| //查询出来的数量 |
| long numFound = results.getNumFound(); |
| System.out.println(“总查询出:” + numFound + “条记录”); |
| //遍历搜索记录 |
| //获取高亮信息 |
| Map |
| for (SolrDocument solrDocument : results) { |
| System.out.println(“商品id:” + solrDocument.get(“id”)); |
| System.out.println(“商品名称 :” + solrDocument.get(“product_name”)); |
| System.out.println(“商品分类:” + solrDocument.get(“product_catalog”)); |
| System.out.println(“商品分类名称:” + solrDocument.get(“product_catalog_name”)); |
| System.out.println(“商品价格:” + solrDocument.get(“product_price”)); |
| System.out.println(“商品描述:” + solrDocument.get(“product_description”)); |
| System.out.println(“商品图片:” + solrDocument.get(“product_picture”)); |
| //输出高亮 |
| Map |
| List |
| if(list != null && list.size() > 0){ |
| System.out.println(list.get(0)); |
| } |
| } |
| client.close(); |
| } |
| } |
| 注意:没有索引的域,是不能用作排序的 |



