Solr学习笔记(5)—— Spring Data Solr入门
一、Spring Data Solr简介
前面已经介绍了通过solrJ来操作solr,那么我们如何将Solr的应用集成到Spring中?Spring Data Solr就是为了方便Solr的开发所研制的一个框架,其底层是对SolrJ(官方API)的封装。
二、Spring Data Solr入门案例
2.1 搭建工程
(1)创建maven工程,pom.xml中引入依赖
<dependencies> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-solr</artifactId> <version>1.5.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.2.4.RELEASE</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.9</version> </dependency> </dependencies>
(2)在src/main/resources下创建 applicationContext-solr.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:solr="http://www.springframework.org/schema/data/solr" xsi:schemaLocation="http://www.springframework.org/schema/data/solr http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- solr服务器地址 --> <solr:solr-server id="solrServer" url="http://127.0.0.1:8080/solr" /> <!-- solr模板,使用solr模板可对索引库进行CRUD的操作 --> <bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate"> <constructor-arg ref="solrServer" /> </bean> </beans>
2.2 @Field 注解
创建TbItem实体类,属性使用@Field注解标识 。如果属性与schema.xml中定义的域名称不一致,需要在注解中指定域名称。
public class TbItem implements Serializable{ @Field private Long id; @Field("item_title") private String title; @Field("item_price") private BigDecimal price; @Field("item_image") private String image; @Field("item_goodsid") private Long goodsId; @Field("item_category") private String category; @Field("item_brand") private String brand; @Field("item_seller") private String seller; ....... }
上面属性中,id在schema.xml中有了同名的属性名,所以不用在@Field指定域的名称;而其他属性的名称和schema.xml中相应的field名称并不一致
所以需要在@Field中指定域名称,让实体类的属性与schema.xml中的域相对应。
2.3 增加(修改)
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:applicationContext-solr.xml") public class TestTemplate { @Autowired private SolrTemplate solrTemplate; @Test public void testAdd() { TbItem item = new TbItem(); item.setId(1L); item.setBrand("小米"); item.setCategory("手机"); item.setGoodsId((1L)); item.setSeller("小米之家"); item.setTitle("小米9透明尊享版"); item.setPrice(new BigDecimal(3999)); solrTemplate.saveBean(item); solrTemplate.commit(); } }
2.4 按主键查询
@Test public void testFindOne() { TbItem item = solrTemplate.getById(1, TbItem.class); System.out.println(item.getTitle()); }
2.5 按主键删除
@Test public void testDelete() { solrTemplate.deleteById("1"); solrTemplate.commit(); }
2.6 分页查询
首先循环插入100条测试数据
@Test public void testAddList() { List<TbItem> list = new ArrayList<TbItem>(); for (int i = 0; i < 99; i++) { TbItem item = new TbItem(); item.setId(i+1L); item.setBrand("小米"+i); item.setCategory("手机"); item.setGoodsId((i+1L)); item.setSeller("小米之家"); item.setTitle("小米9透明尊享版"+i); item.setPrice(new BigDecimal(3999)); list.add(item); } solrTemplate.saveBeans(list); solrTemplate.commit(); }
编写分页查询测试代码:
@Test public void testPageQuery() { Query query = new SimpleQuery("*:*"); query.setOffset(20);//开始索引(默认0) query.setRows(20);//每页记录数(默认10) ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class); System.out.println("总记录数:" + page.getTotalElements()); List<TbItem> list = page.getContent(); for (TbItem item : list) { System.out.println(item.getTitle() +"---"+ item.getPrice()); } }
2.7 条件查询
@Test public void testPageQueryMutil() { Query query = new SimpleQuery("*:*"); Criteria criteria = new Criteria("item_title").contains("小米"); criteria = criteria.and("item_price").is(3999.0); query.addCriteria(criteria); ScoredPage<TbItem> page = solrTemplate.queryForPage(query, TbItem.class); System.out.println("总记录数:" + page.getTotalElements()); List<TbItem> list = page.getContent(); for (TbItem item : list) { System.out.println(item.getTitle() +"---"+ item.getPrice()); } }
2.8 高亮显示结果
/** * 根据关键字搜索列表 * @param searchMap * @return */ private Map searchList(Map searchMap) { Map map = new HashMap(); SimpleHighlightQuery query = new SimpleHighlightQuery(); // 设置高亮的域 HighlightOptions highlightOptions = new HighlightOptions().addField("item_title"); // 高亮前缀 highlightOptions.setSimplePrefix("<em style='color:red'>"); // 高亮后缀 highlightOptions.setSimplePostfix("</em>"); // 设置高亮显示 query.setHighlightOptions(highlightOptions); // 按照关键字查询 Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords")); query.addCriteria(criteria); HighlightPage<TbItem> page = solrTemplate.queryForHighlightPage(query, TbItem.class); // 循环高亮入口集合 for (HighlightEntry<TbItem> entry : page.getHighlighted()) { // 获取原实体类 TbItem item = entry.getEntity(); if (entry.getHighlights().size() > 0 && entry.getHighlights().get(0).getSnipplets().size() > 0) { // 设置高亮结果 item.setTitle(entry.getHighlights().get(0).getSnipplets().get(0)); } } map.put("rows", page.getContent()); return map; }
2.9 分组查询
/** * 查询分类列表 * @param searchMap * @return */ private List searchCategoryList(Map searchMap){ List<String> list=new ArrayList(); Query query=new SimpleQuery(); //按照关键字查询 Criteria criteria=new Criteria("item_keywords").is(searchMap.get("keywords")); query.addCriteria(criteria); //设置分组选项 GroupOptions groupOptions=new GroupOptions().addGroupByField("item_category"); query.setGroupOptions(groupOptions); //得到分组页 GroupPage<TbItem> page = solrTemplate.queryForGroupPage(query, TbItem.class); //根据列得到分组结果集 GroupResult<TbItem> groupResult = page.getGroupResult("item_category"); //得到分组结果入口页 Page<GroupEntry<TbItem>> groupEntries = groupResult.getGroupEntries(); //得到分组入口集合 List<GroupEntry<TbItem>> content = groupEntries.getContent(); for(GroupEntry<TbItem> entry:content){ list.add(entry.getGroupValue());//将分组结果的名称封装到返回值中 } return list; }
2.10 删除全部数据
@Test public void testDeleteAll() { Query query = new SimpleQuery("*:*"); solrTemplate.delete(query); solrTemplate.commit(); }