Spring Data Solr常见操作

①Spring Data Solr简介

虽然支持任何编程语言的能力具有很大的市场价值,你可能感兴趣的问题是:我如何将Solr的应用集成到Spring中?可以,Spring Data Solr就是为了方便Solr的开发所研制的一个框架,其底层是对SolrJ(官方API)的封装。

②使用

导入maven依赖

	<dependency>
		<groupId>org.springframework.data</groupId>
		<artifactId>spring-data-solr</artifactId>
		<version>1.5.5.RELEASE</version>
	</dependency>

添加配置文件

<?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/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 http://www.springframework.org/schema/data/solr http://www.springframework.org/schema/data/solr/spring-solr-1.0.xsd ">
	
	<!-- solr服务器地址 -->
	<solr:solr-server id="solrServer" url="http://192.168.25.134:8080/solr" />

   
	<!-- solr模板,使用solr模板可对索引库进行CRUD的操作 -->
	<bean id="solrTemplate" class="org.springframework.data.solr.core.SolrTemplate">
		<constructor-arg ref="solrServer"/>
	</bean>
</beans>

对实体进行@Field注解

publicclassTbItemimplements Serializable{

    @Field
    private Long id;

    @Field("item_title")
    private String title;

通过Spring Data Solr实现增删查改

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext-solr.xml")
publicclass TestTemplate {

	@Autowired
	private SolrTemplate solrTemplate;
	-----------添加-----------
	@Test
	publicvoid testAdd(){
		TbItem item=new TbItem();
		item.setId(1L);
		item.setBrand("华为");
		item.setCategory("手机");
		item.setGoodsId(1L);
		item.setSeller("华为2号专卖店");
		item.setTitle("华为Mate9");
		item.setPrice(new BigDecimal(2000));		
		solrTemplate.saveBean(item);
		solrTemplate.commit();
	}
	-----------查询-----------
	@Test
	publicvoid testFindOne(){
		TbItem item = solrTemplate.getById(1, TbItem.class);
		System.out.println(item.getTitle());
	}
	-----------删除-----------
	@Test
	publicvoid testDelete(){
		solrTemplate.deleteById("1");
		solrTemplate.commit();
	}
	-----------分页添加数据-----------
	@Test
	publicvoid testAddList(){
		List<TbItem>list=new ArrayList();
		
		for(inti=0;i<100;i++){
			TbItem item=new TbItem();
			item.setId(i+1L);
			item.setBrand("华为");
			item.setCategory("手机");
			item.setGoodsId(1L);
			item.setSeller("华为2号专卖店");
			item.setTitle("华为Mate"+i);
			item.setPrice(new BigDecimal(2000+i));	
			list.add(item);
		}
		
		solrTemplate.saveBeans(list);
		solrTemplate.commit();
	}
	-----------分页查询-----------
	@Test
	publicvoidtestPageQuery(){
		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();
		showList(list);//show code ignore
	}
	-----------条件查询-----------
    @Test
	publicvoid testPageQueryMutil(){	
		Query query=new SimpleQuery("*:*");
		Criteria criteria=new Criteria("item_title").contains("2");
		criteria=criteria.and("item_title").contains("5");		
		query.addCriteria(criteria);
		//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();
		showList(list);
	}
	-----------删除全部-----------
	@Test
	publicvoidtestDeleteAll(){
		Query query=new SimpleQuery("*:*");
		solrTemplate.delete(query);
		solrTemplate.commit();
	}


}

批量导入数据

注:这里导入的时候使用了动态域

    @Dynamic
    @Field("item_spec_*")
    private Map<String,String> specMap;

@Component
public class SolrUtil {

	@Autowired
	private TbItemMapper itemMapper;
	
	@Autowired
	private SolrTemplate solrTemplate;
	
	public void importItemData(){
		
		TbItemExample example=new TbItemExample();
		Criteria criteria = example.createCriteria();
		criteria.andStatusEqualTo("1");//审核通过的才导入的
		List<TbItem> itemList = itemMapper.selectByExample(example);
		
		System.out.println("---商品列表---");
		int count=0;
		for(TbItem item:itemList){
			System.out.println(item.getId()+" "+ item.getTitle()+ " "+item.getPrice()+(++count));	
			Map specMap = JSON.parseObject(item.getSpec(), Map.class);//从数据库中提取规格json字符串转换为map
			item.setSpecMap(specMap);
		}
		
		solrTemplate.saveBeans(itemList);
		solrTemplate.commit();
		
		System.out.println("---结束---");
	}
	
	public void execute(){
		ApplicationContext context=new ClassPathXmlApplicationContext("classpath*:spring/applicationContext*.xml");
		SolrUtil solrUtil=  (SolrUtil) context.getBean("solrUtil");
		solrUtil.importItemData();
	}
	
}

关键字查询

@Service(timeout=3000)
publicclass ItemSearchServiceImpl implements ItemSearchService{
	@Autowired
	private SolrTemplate solrTemplate;

	@Override
	public Map<String, Object> search(MapsearchMap) {
Map<String,Object>map=new HashMap<>();
		Query query=new SimpleQuery();
		//添加查询条件
		Criteria criteria=new Criteria("item_keywords").is(searchMap.get("keywords"));
		query.addCriteria(criteria);
		ScoredPage<TbItem>page = solrTemplate.queryForPage(query, TbItem.class);
		map.put("rows", page.getContent());
		returnmap;
	}
}

关键字高亮显示


	/**
	 * 根据关键字搜索列表
	 * @param keywords
	 * @return
	 */
	privateMap searchList(MapsearchMap){
		Mapmap=newHashMap();
		HighlightQuery 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>h: page.getHighlighted()){//循环高亮入口集合
			TbItem item = h.getEntity();//获取原实体类			
			if(h.getHighlights().size()>0 &&h.getHighlights().get(0).getSnipplets().size()>0){
				item.setTitle(h.getHighlights().get(0).getSnipplets().get(0));//设置高亮的结果
			}			
		}		
		map.put("rows",page.getContent());
		returnmap;
	}

注:我们测试后发现高亮显示的html代码原样输出,这是angularJS为了防止html攻击采取的安全机制。我们如何在页面上显示html的结果呢?我们会用到$sce服务的trustAsHtml方法来实现转换。

  1. 修改base.js

// 定义模块:

var app = angular.module("pinyougou",[]);

/*$sce服务写成过滤器*/

app.filter('trustHtml',['$sce',function($sce){

    return function(data){

        return $sce.trustAsHtml(data);   

    }

}]);

      2.使用过滤器

      ng-bind-html指令用于显示html内容

      竖线 |用于调用过滤器

<divclass="attr"ng-bind-html="item.title | trustHtml"></div>

 

分组查询:返回一个List<String>

	/**
	 * 查询分类列表  
	 * @param searchMap
	 * @return
	 */
import org.springframework.data.domain.Page;

	privateList searchCategoryList(MapsearchMap){
		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;
	}

过滤查询

	/**
	 * 根据关键字搜索列表
	 * @param keywords
	 * @return
	 */
	privateMap searchList(Map searchMap){
		.......
		//1.1关键字查询......	
		//1.2按分类筛选
		if(!"".equals(searchMap.get("category"))){			
			Criteria filterCriteria=new Criteria("item_category").is(searchMap.get("category"));
			FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
			query.addFilterQuery(filterQuery);
		}
		//高亮显示处理.....		
	}

价格区间过滤

	/**
	 * 根据关键字搜索列表
	 * @param keywords
	 * @return
	 */
	privateMap searchList(Map searchMap){
         ......		
		//1.1关键字查询.....
		//1.2按分类筛选.....
		//1.3按品牌筛选.....
		//1.4过滤规格	......
		//1.5按价格筛选.....
		if(!"".equals(searchMap.get("price"))){
			String[] price = ((String) searchMap.get("price")).split("-");
			if(!price[0].equals("0")){//如果区间起点不等于0
				Criteria filterCriteria=new Criteria("item_price").greaterThanEqual(price[0]);
				FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
				query.addFilterQuery(filterQuery);				
			}		
			if(!price[1].equals("*")){//如果区间终点不等于*
				Criteria filterCriteria=new  Criteria("item_price").lessThanEqual(price[1]);
				FilterQuery filterQuery=new SimpleFilterQuery(filterCriteria);
				query.addFilterQuery(filterQuery);				
			}
		}		
		//高亮显示处理	.....
	}

分页查询


	/**
	 * 根据关键字搜索列表
	 * @param keywords
	 * @return
	 */
	privateMap searchList(MapsearchMap){
		.....
		//1.1关键字查询
		.....	
		//1.2按分类筛选
		.....
		//1.3按品牌筛选
		.....
		//1.4过滤规格
		.....		
		//1.5按价格筛选
		......		
		//1.6 分页查询		
		Integer pageNo= (Integer) searchMap.get("pageNo");//提取页码
		if(pageNo==null){
			pageNo=1;//默认第一页
		}
		Integer pageSize=(Integer) searchMap.get("pageSize");//每页记录数 
		if(pageSize==null){
			pageSize=20;//默认20
		}
		query.setOffset((pageNo-1)*pageSize);//从第几条记录查询
		query.setRows(pageSize);		
		//高亮显示处理
		......
		Map map=new HashMap<>();
		map.put("rows", page.getContent());		
		map.put("totalPages", page.getTotalPages());//返回总页数
		map.put("total", page.getTotalElements());//返回总记录数
		return map;
	}

 排序

	/**
	 * 根据关键字搜索列表
	 * @param keywords
	 * @return
	 */
	privateMap searchList(Map searchMap){
		........
		//1.7排序
		String sortValue= (String) searchMap.get("sort");//ASC  DESC  
		String sortField= (String) searchMap.get("sortField");//排序字段
		if(sortValue!=null&& !sortValue.equals("")){  
			if(sortValue.equals("ASC")){
				Sort sort=new Sort(Sort.Direction.ASC, "item_"+sortField);
				query.addSort(sort);
			}
			if(sortValue.equals("DESC")){		
				Sort sort=new Sort(Sort.Direction.DESC, "item_"+sortField);
				query.addSort(sort);
			}			
		}
		//高亮显示处理
		......
		return map;
	}

SpringDataSolr连接SolrCloud

在SolrJ中提供一个叫做CloudSolrServer的类,它是SolrServer的子类,用于连接solrCloud

它的构造参数就是zookeeper的地址列表,另外它要求要指定defaultCollection属性(默认的 collection名称)

我们现在修改springDataSolrDemo工程的配置文件 ,把原来的solr-server注销,替换为CloudSolrServer .指定构造参数为地址列表,设置默认 collection名称

	<!-- solr服务器地址
	<solr:solr-server id="solrServer"url="http://192.168.25.129:8080/solr" />
	 -->	
	<bean id="solrServer" class="org.apache.solr.client.solrj.impl.CloudSolrServer">
		<constructor-argvalue="192.168.25.135:2181,192.168.25.135:2182,192.168.25.135:2183"/>
		<property name="defaultCollection" value="collection1"></property>
	</bean>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值