solr实战项目中应用

@Component
public class SolrUtil {

	@Autowired
	private TbItemMapper tbItemMapper;
	
	@Autowired
	private SolrTemplate solrTemplate;
	public void importItemData() {
		TbItemExample example = new TbItemExample();
		Criteria criteria = example.createCriteria();
		criteria.andStatusEqualTo("1");
		List<TbItem> itemList = tbItemMapper.selectByExample(example);
		for (TbItem item : itemList) {
			//spec在搜索中是动态域,在实体类中建立一个属性map,并且要加上@Dynamic和@Field("item_spec_*")注解
			//JSON.parseArray 是针对[]开头的字符串转换成集合 ,JSON.parseObject是针对{}开头的字符串转换成集合
			//
			Map map = JSON.parseObject(item.getSpec(), Map.class);
			item.setMapSpec(map);
		}
		
		solrTemplate.saveBeans(itemList);
		solrTemplate.commit();
	}
	
	public static void main(String[] args) {
		//@component (把普通pojo实例化到spring容器中,相当于配置文件中的<bean id="" class=""/>)
		//原生读取xml文件的方式,第一个classpath如果不加*则只能读取当前工程下的配置文件,第二个*是通配符表示以applicationContext开头的xml都要去读
		//然而当前需要读取不仅是当前工程的xml还要读取Dao的xml,且其下配置文件是applicationContext-service.xml
		ApplicationContext context = new ClassPathXmlApplicationContext("classpath*:spring/applicationContext*.xml");
		//spring读取bean创建一个队象,默认是以当前类第一个字母小写来创建队象
		SolrUtil solrUtil = (SolrUtil) context.getBean("solrUtil");
		solrUtil.importItemData();
	}
}

关键字高亮查询

@Service(timeout=5000)
public class ItemSearchServiceImpl implements ItemSearchService {

	@Autowired
	private SolrTemplate solrTemplate;
	
	/**
	 * item_keyword是solr的一个复制域,其值包括item_title,item_category,item_seller,item_brand
	 * 所以搜索匹配实体用item_keyword比较全面
	 */
	@Override
	public Map search(Map searchMap) {
		Map 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());*/
		
		// HighlightQuery(接口)是Query(接口)的子接口
		
		//高亮查询对象
		HighlightQuery query = new SimpleHighlightQuery();
		
		
		//设置高亮选项,API 底层是形如【 <em style='color:red'>三星</em>智能手机】
		//设置高亮需明确  1.在哪列加高亮 2.前缀的样式 3.后缀的样式
		//1.在哪列加高亮  。addField 设置solr 域在查询的哪一列加高亮可以是多个(如item_title,item_category,item_seller...)
		HighlightOptions highlightOptions = new HighlightOptions().addField("item_title");
		
		//2.前缀的样式 
		highlightOptions.setSimplePrefix("<em style='color:red'>");
		
		//3.后缀的样式
		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);
		
		//高亮入口集合(其实是查询出来得每一条记录)每个高亮记录的入口
		List<HighlightEntry<TbItem>> entryList = page.getHighlighted();
		for(HighlightEntry<TbItem> entry: entryList) {
			
			//获取高亮列表(需要被高亮的列当前是:item_title)高亮列的个数
			List<Highlight> highlights = entry.getHighlights();
			//没有程序出错,增加程序健壮性
			if(highlights.size() > 0) {
				for(Highlight highlight : highlights) {
					
					//solr每个域中可以存储多个<field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
					List<String> snipplets = highlight.getSnipplets();
					//没有程序出错,增加程序健壮性
					if (snipplets.size() > 0) {
						//得到每个域中的每个值如item_title,item_category,item_seller...
						for (String everyItem : snipplets) {
							//这个item就是page.getContent()对象
							TbItem item = entry.getEntity();
							item.setTitle(everyItem);
						}
					}
				}	
			}
			
		}
		
		
		map.put("rows", page.getContent());
		return map;
	}

}
/**
	 * 搜索高亮显示
	 * @param searchMap
	 * @return
	 */
	public Map searchList(Map searchMap) {
		Map map = new HashMap();
		// HighlightQuery(接口)是Query(接口)的子接口
		
		//构建高亮查询对象
		HighlightQuery query = new SimpleHighlightQuery();
		
		
		//设置高亮选项,API 底层是形如【 <em style='color:red'>三星</em>智能手机】
		//设置高亮需明确  1.在哪列加高亮 2.前缀的样式 3.后缀的样式
		//1.在哪列加高亮  。addField 设置solr 域在查询的哪一列加高亮可以是多个(如item_title,item_category,item_seller...)
		HighlightOptions highlightOptions = new HighlightOptions().addField("item_title");
		
		//2.前缀的样式 ,angualrjs需要过滤器进行转换,其他不用
		highlightOptions.setSimplePrefix("<em style='color:red'>");
		
		//3.后缀的样式
		highlightOptions.setSimplePostfix("</em>");
		//为查询对象设置高亮选项
		query.setHighlightOptions(highlightOptions);
		
		//1.1高亮字查询
		//构建查询条件:指定域(item_keywords)查询的关键字(item_keywords)
		Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));
		query.addCriteria(criteria);
		
		//1.2按商品分类查询
		if (!"".equals(searchMap.get("category"))) {
			FilterQuery filterQuery = new SimpleFilterQuery();
			Criteria filterCriteria = new Criteria("item_category").is(searchMap.get("category"));
			filterQuery.addCriteria(filterCriteria );
			query.addFilterQuery(filterQuery );
		}
		
		//1.3按品牌查询
		if (!"".equals(searchMap.get("brand"))) {
			FilterQuery filterQuery = new SimpleFilterQuery();
			Criteria filterCriteria = new Criteria("item_brand").is(searchMap.get("brand"));
			filterQuery.addCriteria(filterCriteria );
			query.addFilterQuery(filterQuery );
		}
		
		//1.4按规格查询
		if (searchMap.get("spec") != null) {
			//前段过来的格式是{'网络':'移动4G','内存','128G'}其本身就是个Map,所以不用json转,直接强制转换即可
			Map<String, String> specMap = (Map<String, String>) searchMap.get("spec");
			for (String key : specMap.keySet()) {
				FilterQuery filterQuery = new SimpleFilterQuery();
				Criteria filterCriteria = new Criteria("item_spec_"+key).is(specMap.get(key));
				filterQuery.addCriteria(filterCriteria );
				query.addFilterQuery(filterQuery );
			}
		}
		
        //1.5按价格查询
		if (!"".equals(searchMap.get("price"))) {
			String[] price = ((String)searchMap.get("price")).split("-");
			//最低价条件查询
			if (!"0".equals(price[0])) {//如果最低价格不等0
				FilterQuery filterQuery = new SimpleFilterQuery();
				Criteria filterCriteria = new Criteria("item_price").greaterThanEqual(price[0]);
				filterQuery.addCriteria(filterCriteria);
				query.addFilterQuery(filterQuery);
			}
			//最高价条件查询
			if (!"*".equals(price[1])) {//如果最低价格不等0
				FilterQuery filterQuery = new SimpleFilterQuery();
				Criteria filterCriteria = new Criteria("item_price").lessThanEqual(price[1]);
				filterQuery.addCriteria(filterCriteria );
				query.addFilterQuery(filterQuery );
			}
		}

	
		//1.6分页查询
		Integer pageNum =(Integer) searchMap.get("pageNo");
		if (pageNum == null) {
			pageNum =1;
		}
		Integer pageSize =(Integer) searchMap.get("pageSize");
		if (pageSize == null) {
			pageSize = 20;
		}
		//原生的limit分页就可以用这种方式
		query.setOffset((pageNum-1)*pageSize);//得到起始页的索引(公式:(页数-1)*页的长度,并不是页数,
		query.setRows(pageSize);

		//**************  获取高亮结果集         **********
		//获取高亮页对象
		HighlightPage<TbItem> page = solrTemplate.queryForHighlightPage(query, TbItem.class);
		//高亮入口集合(其实是查询出来得每一条记录)每个高亮记录的入口
		List<HighlightEntry<TbItem>> entryList = page.getHighlighted();
		for(HighlightEntry<TbItem> entry: entryList) {
			
			//获取高亮列表(需要被高亮的列当前是:item_title)高亮列的个数
			List<Highlight> highlights = entry.getHighlights();
			//没有程序出错,增加程序健壮性
			if(highlights.size() > 0) {
				for(Highlight highlight : highlights) {
					
					//solr每个域中可以存储多个<field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
					List<String> snipplets = highlight.getSnipplets();
					//没有程序出错,增加程序健壮性
					if (snipplets.size() > 0) {
						//得到每个域中的每个值如item_title,item_category,item_seller...
						for (String everyItem : snipplets) {
							//这个item就是page.getContent()对象
							TbItem item = entry.getEntity();
							item.setTitle(everyItem);
						}
					}
				}	
			}
			
		}
		
		map.put("rows", page.getContent());

//总页数
		map.put("totalPages", page.getTotalPages());
		//总条数
		map.put("total", page.getTotalElements());
		return map;
	}

Dobux配置请求超时@Service(timeout=5000)
@RequestBody:前台请求是一个对象使用的注解@RequestBody Map searchMap

/**
	 * 查询商品分类列表(相当于分组查询,但实际不是)
	 * @param searchMap
	 * @return
	 */
	public List<String> searchCategoryList(Map searchMap) {
		List<String> list = new ArrayList<String>();
		
		//1.创建查询队象
		Query query = new  SimpleQuery("*:*");
		
		//2.构建查询条件(添加可能查询的值):(item_keywords(复制域)复制域的好处是可以包含所有查询类型)查询的关键字(item_keywords)
		Criteria criteria = new Criteria("item_keywords").is(searchMap.get("keywords"));//相当于sql中的wehere = ?
		query.addCriteria(criteria);
		
		//3.构建分组选项(指定查询的域可有多个)
		GroupOptions groupOptions = new GroupOptions().addGroupByField("item_category");//相当于sql中的group by XXX
		query.setGroupOptions(groupOptions );
		
		//4.得到分组页对象
		//执行查询得到分组页对象,【注意】分组页对象也有getContent()方法,但是他的结果是一个空值
		//,是因为他父接口Page是有这个方法他必须有这个方法
		GroupPage<TbItem> groupPage = solrTemplate.queryForGroupPage(query, TbItem.class);//分组页对象
		
		//5.通过分组页对象得到分页组结果对象
		//一个分组对象可以有多个分组结果对象
		GroupResult<TbItem> groupResult = groupPage.getGroupResult("item_category");//分组结果对象
		
		//6.分组结果对象得到分组入口页【注意】分页组结果对象是对象,分组页接口页是集合,他们是包含关系,
		
		Page<GroupEntry<TbItem>> groupEntries = groupResult.getGroupEntries();//分组入口页对象
		
		//7.得到所有分组入口页集合
		List<GroupEntry<TbItem>> content = groupEntries.getContent();//分组入口集合
		
		//8.得到每一个分组入口
		for (GroupEntry<TbItem> groupEntry : content) {
			//分组结果添加到返回值中
			list.add(groupEntry.getGroupValue());
		}
		return list;
	}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值