搜索解决方案 -- solr -- spring data solr
一、Solr的安装与配置
1.1 什么是Solr
Solr是一个开源搜索平台,用于构建搜索应用程序。它建立在Lucene(全文搜索引擎)之上。Solr是企业级的,快速的和高度可扩展的。使用Solr构建的应用程序非常复杂,可提供高性能。
通过使用类似REST的HTTP API,确保了几乎能使用任何编程语言来使用solr。
Solr可以和Hadoop一起使用。由于Hadoop处理大量数据,Solr帮助我们从这么大的源中找到所需的信息。不仅限于搜索,Solr也可以用于存储目的。像其他NoSQL数据库一样,它是一种分关系数据存储和处理技术。
总是,Solr是一个可扩展的,可部署,搜索/存储引擎,优化搜索大量以文本为中心的数据。
1.2 Solr安装
- 安装Tomcat,解压缩就可以了
- 解压solr
- 把solr下的dist目录 solr-4.10.3.war 部署到Tomcat\webapps 下(去掉版本号)。
- 启动Tomcat解压缩war包
- 包solr下example/lib/ext目录下的所有的jar包添加到solr的工程中(\WEB-INF\lib目录下)。
- 创建一个solrhome。solr下的/example/solr目录就是一个solrhome。复制此目录到D盘改名为solrhome
- 关联solr及solrhome。需要修改solr工程的web.xml文件
1 <env-entry> 2 <env-entry-name>solr/home</env-entry-name> 3 <env-entry-value>d:\solrhome</env-entry-value> 4 <env-entry-type>java.lang.String</env-entry-type> 5 </env-entry>
- 启动Tomcat
访问:http://localhost:8080/solr/
1.3 中文分析器IK Analyzer
1.IK Analyzer简介
一个开源的,基于Java语言开发的轻量级的中文分词工具包
2.IK Analyzer配置
步骤:
1、把IKAnalyzer2012FF_u1.jar添加到solr工程的lib目录下
2、创建WEB-INF/classes 文件夹,把扩展词典、停用词词典、配置文件放到solr工程的WEB-INF/classes目录下。
3、修改Solrhome的scheme.xml文件,配置一个FieldType,使用IKAnalyzer
1 <fieldType name="text_ik" class="solr.TextField"> 2 <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/> 3 </fieldType>
1.4 配置域
域相当于数据库的表字段,用户存放数据,因此用户根据业务需要去定义相关的Field(域),一般来说,每一种域对应着一种数据,用户对同一种数据进行相同的操作
域的常用属性:
- name:指定域的名称
- type:指定域的类型
- indexed:是否索引
- stored:是否存储
- required:是否必须
- multiValue的:是否多值
1.域 -- field
修改solrhome的schema.xml文件,设置业务系统Field -- 为下面的demo做铺垫
1 <field name="item_goodsid" type="long" indexed="true" stored="true"/> 2 <field name="item_title" type="text_ik" indexed="true" stored="true"/> 3 <field name="item_price" type="double" indexed="true" stored="true"/> 4 <field name="item_image" type="string" indexed="false" stored="true" /> 5 <field name="item_category" type="string" indexed="true" stored="true" /> 6 <field name="item_seller" type="text_ik" indexed="true" stored="true" /> 7 <field name="item_brand" type="string" indexed="true" stored="true" />
2.复制域 -- copyFiled
1 <field name="item_keywords" type="text_ik" indexed="true" stored="false" 2 multiValued="true"/> 3 <copyField source="item_title" dest="item_keywords"/> 4 <copyField source="item_category" dest="item_keywords"/> 5 <copyField source="item_seller" dest="item_keywords"/> 6 <copyField source="item_brand" dest="item_keywords"/>
3.动态域 -- dynamicField
当我们需要动态扩充字段时,就需要使用到动态域,假设搜索对象为一个商品
1 <dynamicField name="item_spec*" type="string" indexed="true" stored="true" />
二、Spring Data Solr入门
2.1 Spring Data Solr简介
Spring Data Solr是为了方便Solr的一个封装,其底层是对SolrJ(官方API)的封装。
2.2 Spring Data Solr入门小Demo
1.搭建工程
- pom.xml中引入依赖
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 2 <modelVersion>4.0.0</modelVersion> 3 <groupId>com.pinyougou</groupId> 4 <artifactId>Spring-Data-Solr-Demo</artifactId> 5 <version>0.0.1-SNAPSHOT</version> 6 7 <dependencies> 8 <!-- spring-data-solr --> 9 <dependency> 10 <groupId>org.springframework.data</groupId> 11 <artifactId>spring-data-solr</artifactId> 12 <version>1.5.5.RELEASE</version> 13 </dependency> 14 15 <!-- 测试用 --> 16 <dependency> 17 <groupId>org.springframework</groupId> 18 <artifactId>spring-test</artifactId> 19 <version>4.2.4.RELEASE</version> 20 </dependency> 21 <dependency> 22 <groupId>junit</groupId> 23 <artifactId>junit</artifactId> 24 <version>4.9</version> 25 </dependency> 26 </dependencies> 27 </project>
- 创建applicationContext-solr.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:p="http://www.springframework.org/schema/p" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xmlns:solr="http://www.springframework.org/schema/data/solr" 7 xsi:schemaLocation="http://www.springframework.org/schema/data/solr 8 http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd 9 http://www.springframework.org/schema/beans 10 http://www.springframework.org/schema/beans/spring-beans.xsd 11 http://www.springframework.org/schema/context 12 http://www.springframework.org/schema/context/spring-context.xsd"> 13 14 <!-- solr 服务器地址 --> 15 <solr:solr-server id="solrServer" url="http://127.0.0.1:8080/solr" /> 16 17 <!-- solr 模板,使用 solr 模板可对索引库进行 CRUD 的操作 --> 18 <bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate"> 19 <constructor-arg ref="solrServer" /> 20 </bean> 21 </beans>
2.创建搜索对应的商品类
将需要索引的实体类在Item对应的属注解性上使用@Filed注解标识,如果属性与配置文件定义的域名称不一致,需要在注解中指定域名称。
1 public class TbItem implements Serializable { 2 3 @Field 4 private Long id; 5 6 @Field("item_title") 7 private String title; 8 9 @Field("item_price") 10 private BigDecimal price; 11 12 @Field("item_image") 13 private String image; 14 15 @Field("item_goodsid") 16 private Long goodsId; 17 18 @Field("item_category") 19 private String category; 20 21 @Field("item_brand") 22 private String brand; 23 24 @Field("item_seller") 25 private String seller; 26 27 // 省略getter和setter方法 28 }
3.solrTemplate中的常用方法
1 @RunWith(SpringJUnit4ClassRunner.class) 2 @ContextConfiguration(locations = "classpath:applicationContext-solr.xml") 3 public class SolrTest { 4 5 @Autowired 6 private SolrTemplate solrTemplate; 7 8 /** 9 * 测试添加 -- 执行增删改需要进行commit提交 10 */ 11 @Test 12 public void testAdd() { 13 TbItem item = new TbItem(); 14 item.setId(1L); 15 item.setBrand("华为"); 16 item.setCategory("手机"); 17 item.setGoodsId(1L); 18 item.setSeller("华为1号专卖店"); 19 item.setTitle("华为Mate9"); 20 item.setPrice(new BigDecimal(2000)); 21 22 solrTemplate.saveBean(item); 23 solrTemplate.commit(); 24 } 25 26 /** 27 * 测试根据主键查找一个 28 */ 29 @Test 30 public void testFindOne() { 31 TbItem item = solrTemplate.getById(1, TbItem.class); 32 System.out.println(item.getTitle()); 33 } 34 35 /** 36 * 测试根据主键删除 37 */ 38 @Test 39 public void testDele() { 40 for (int i = 2; i <= 100; i++) { 41 solrTemplate.deleteById("" + i + ""); 42 solrTemplate.commit(); 43 } 44 45 } 46 47 /** 48 * 测试添加一个集合 49 */ 50 @Test 51 public void testAddList() { 52 ArrayList<TbItem> list = new ArrayList<TbItem>(); 53 54 for (int i = 0; i < 100; i++) { 55 TbItem item = new TbItem(); 56 item.setId(i + 1L); 57 item.setBrand("华为"); 58 item.setCategory("手机"); 59 item.setGoodsId(1L); 60 item.setSeller("华为 2 号专卖店"); 61 item.setTitle("华为 Mate" + i); 62 item.setPrice(new BigDecimal(2000 + i)); 63 list.add(item); 64 } 65 66 solrTemplate.saveBeans(list); 67 solrTemplate.commit(); 68 69 } 70 71 /** 72 * 测试分页查询 73 */ 74 public void testPageQuery() { 75 Query query = new SimpleQuery("*:*"); 76 query.setOffset(20);// 开始索引 77 query.setRows(20);// 每页记录数 78 ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class); 79 List<TbItem> list = page.getContent(); 80 for (TbItem item : list) { 81 System.out.println(item.getTitle()); 82 } 83 84 } 85 86 /** 87 * 测试条件查询 88 */ 89 public void testPageQueryMutil() { 90 Query query = new SimpleQuery("*:*"); 91 Criteria criteria = new Criteria("item_title").contains("2"); 92 criteria = criteria.and("item_title").contains("5"); 93 query.addCriteria(criteria); 94 ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class); 95 System.out.println("总记录数:" + page.getTotalElements()); 96 List<TbItem> list = page.getContent(); 97 for (TbItem item : list) { 98 System.out.println(item.getTitle()); 99 } 100 } 101 102 /** 103 * 测试删除所有 104 */ 105 public void testDeleAll() { 106 Query query = new SimpleQuery("*:*"); 107 solrTemplate.delete(query); 108 solrTemplate.commit(); 109 } 110 }
这里就不一一展示了,有兴趣的执行一下,有想用SpringBoot做一下,但是SpringBoot中的SolrTemplate的方法和上面的有点不一样,SolrClient的方法和上面使用的SolrTemplate中差不多。下次有机会再尝试。