利用solr实现商品的搜索功能(实例讲解)

利用solr实现商品的搜索功能(实例讲解)

转载  2017-11-28   作者:小虾米的java梦    我要评论

下面小编就为大家分享一篇利用solr实现商品的搜索功能,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

后期补充:

为什么要用solr服务,为什么要用luncence?

问题提出:当我们访问购物网站的时候,我们可以根据我们随意所想的内容输入关键字就可以查询出相关的内容,这是怎么做到呢?这些随意的数据不可能是根据数据库的字段查询的,那是怎么查询出来的呢,为什么千奇百怪的关键字都可以查询出来呢?

答案就是全文检索工具的实现,luncence采用了词元匹配和切分词。举个例子:北京天安门------luncence切分词:北京 京天 天安 安门 等等这些分词。所以我们搜索的时候都可以检索到。

有一种分词器就是IKAnalyzer中文分词器,它有细粒度切分和智能切分,即根据某种智能算法。

这就使用solr的最大的好处:检索功能的实现。

使用步骤;

(1)solr服务器搭建,因为solr是用java5开发的,所以需要jdk和tomcat。搭建部署

(2)搭建完成后,我们需要将要展示的字段引入solr的库中。配置spring与solr结合,工程启动的时候启动solr

(3)将数据库中的查询内容导入到solr索引库,这里使用的是solrj的客户端实现的。具体使用可以参考api

(4)建立搜索服务,供客户端调用。调用solr,查询内容,这中间有分页功能的实现。solr高亮显示的实现。

(5)客户端接收页面的请求参数,调用搜索服务,进行搜索。

业务字段判断标准:

1、在搜索时是否需要在此字段上进行搜索。例如:商品名称、商品的卖点、商品的描述

(这些相当于将标签给了solr,导入商品数据后,solr对这些字段的对应的商品的具体内容进行分词切分,然后,我们就可以搜索到相关内容了)

2、后续的业务是否需要用到此字段。例如:商品id。

需要用到的字段:

1、商品id

2、商品title

3、卖点

4、价格

5、商品图片

6、商品分类名称

7、商品描述

Solr中的业务字段:

1、id——》商品id

其他的对应字段创建solr的字段。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
< field name = "item_title" type = "text_ik" indexed = "true" stored = "true" />
 
< field name = "item_sell_point" type = "text_ik" indexed = "true" stored = "true" />
 
< field name = "item_price" type = "long" indexed = "true" stored = "true" />
 
< field name = "item_image" type = "string" indexed = "false" stored = "true" />
 
< field name = "item_category_name" type = "string" indexed = "true" stored = "true" />
 
< field name = "item_desc" type = "text_ik" indexed = "true" stored = "false" />
 
  
 
< field name = "item_keywords" type = "text_ik" indexed = "true" stored = "false" multiValued = "true" />
 
< copyField source = "item_title" dest = "item_keywords" />
 
< copyField source = "item_sell_point" dest = "item_keywords" />
 
< copyField source = "item_category_name" dest = "item_keywords" />
 
< copyField source = "item_desc" dest = "item_keywords" />

重新启动tomcat

Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器。Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。

Solr是一个全文检索服务器,只需要进行配置就可以实现全文检索服务。有效降低频繁访问数据库对数据库造成的压力。

第一步:将solr部署在linux系统下。

第二步:solrJ是solr的客户端,使用它需要依赖solrJ的jar包。

第三步:将数据库的内容添加到solr的索引库,这样查询就在索引库查询,而不是数据库了。

controller层:

?
1
2
3
4
5
6
7
8
9
10
11
12
@Controller
@RequestMapping("/manager")
public class ItemController {
  @Autowired
  private ItemService itemService;
  @RequestMapping("/importall")
  @ResponseBody
  public TaotaoResult importAllItem(){
    TaotaoResult result= itemService.importAllItem();
    return result;
  }
}< br >service层编写:< br >多表查询商品,显示在页面的逻辑编写:< br >mapper.java
?
1
2
3
4
5
6
7
8
9
10
package com.taotao.search.mapper;
  
import java.util.List;
  
import com.taotao.search.pojo.Item;
  
public interface ItemMapper {
  List< Item > getItemList();
  
}

mapper.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<? xml version = "1.0" encoding = "UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
< mapper namespace = "com.taotao.search.mapper.ItemMapper" >
< select id = "getItemList" resultType = "com.taotao.search.pojo.Item" >
  SELECT
  a.id,
  a.title,
  a.sell_point,
  a.price,
  a.image,
  b. NAME category_name
  FROM
  tb_item a
  LEFT JOIN tb_item_cat b ON a.cid = b.id
</ select >
</ mapper >

第四步:从索引库查询的逻辑编写:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//从索引库里面获取商品信息,现在这个dao层是从索引库获取信息,因为之前的写的逻辑是将db里面的数据导入到索引库。后面的查询都是从索引库中进行,而不从数据库了
@Repository
public class SearchDaoImpl implements SearchDao {
  @Autowired
  private SolrServer solrServer;
  
  @Override
  public SearchResult search(SolrQuery query) throws Exception {
   //这是从索引库里面,直接执行查询
   QueryResponse response = solrServer.query(query);
   //获取查询的结果
   SolrDocumentList documentList= response.getResults();
    
   SearchResult result=new SearchResult();
   //这是获取总记录数
   result.setRecordCount(documentList.getNumFound());
    
   List< Item > itemList=new ArrayList<>();
   //商品的高亮显示,即当鼠标移到字上时,该字体变色,这是从QueryResponse中获取的
   Map< String , Map<String, List<String>>> highlighting = response.getHighlighting();
    
   for (SolrDocument solrDocument : documentList) {
     
    //每个SolrDocument都是一个商品pojo的内容,所以这里要创建一个商品的pojo对象,来获取详细的字段
    Item item=new Item();
    item.setId((String) solrDocument.get("id"));
    //高亮显示是title的高亮显示
    List< String > list = highlighting.get(solrDocument.get("id")).get("item_title");
    String title="";
    if (list!=null && list.size()>0) {
     title=list.get(0);
    }
    else{
     title=(String) solrDocument.get("item_title");
    }
    
    item.setTitle(title);
    item.setPrice((Long) solrDocument.get("item_price"));
    item.setImage((String) solrDocument.get("item_image"));
    item.setCategory_name((String) solrDocument.get(" item_category_name"));
    item.setSell_point((String) solrDocument.get("item_sell_point"));
    itemList.add(item);
   }
    
    result.setItemList(itemList);
   
   return result;
  }
  
}

第五步:索引库内容建立好后,开始编写对外的服务接口,即通过条件搜索具体的商品,比如手机,会显示出总共的手机列表信息,第几页,总共多少页,总共多少个搜索结果

请求的url:

/search/query?q={查询条件}&page={page}&rows={rows}

返回的结果:TaotaoResult包装商品列表。

创建一个sql语句对应的pojo,单独建立一个pojo

用来装显示的内容列表:

?
1
2
3
4
5
6
7
8
9
10
public class Item {
   private String id;
   private String title;
   private String sell_point;
   private long price;
   private String image;
   private String category_name;
   private String item_des;
  
}

controller层:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
@Controller
public class SearchController {
  @Autowired
  private SearchService searchService;
   
  @RequestMapping(value="/query", method=RequestMethod.GET)
  @ResponseBody
  public TaotaoResult search(@RequestParam("q")String queryString,
    @RequestParam(defaultValue="1")Integer page,
    @RequestParam(defaultValue="60")Integer rows) {
   //查询条件不能为空
   if (StringUtils.isBlank(queryString)) {
    return TaotaoResult.build(400, "查询条件不能为空");
   }
   SearchResult searchResult = null;
   try {
    queryString = new String(queryString.getBytes("iso8859-1"), "utf-8");
    searchResult = searchService.search(queryString, page, rows);
   } catch (Exception e) {
    e.printStackTrace();
    return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
   }
   return TaotaoResult.ok(searchResult);
    
  }
  }< br >< br >< br >
1
< span style = "font-size: 16px" >service层:利用solrJ的solrQurery来查询:</ span >

前提是要写好如何从索引库读取数据:  

下面是服务的接口层编写:

controller:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Controller
public class SearchController {
  @Autowired
  private SearchService searchService;
   
  @RequestMapping(value="/query", method=RequestMethod.GET)
  @ResponseBody
  public TaotaoResult search(@RequestParam("q")String queryString,
    @RequestParam(defaultValue="1")Integer page,
    @RequestParam(defaultValue="60")Integer rows) {
   //查询条件不能为空
   if (StringUtils.isBlank(queryString)) {
    return TaotaoResult.build(400, "查询条件不能为空");
   }
   SearchResult searchResult = null;
   try {
    queryString = new String(queryString.getBytes("iso8859-1"), "utf-8");
    searchResult = searchService.search(queryString, page, rows);
   } catch (Exception e) {
    e.printStackTrace();
    return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
   }
   return TaotaoResult.ok(searchResult);
    
  }
  }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@Service
public class SearchServiceImpl implements SearchService {
  @Autowired
  private SearchDao searchDao;
   
  
  @Override
  public SearchResult search(String queryString, int page, int rows) throws Exception {
  SolrQuery query=new SolrQuery();
  query.setQuery(queryString);
  query.setStart((page-1)*rows);
  query.setRows(rows);
  //设置默认的查询搜索域,即默认的查询
  query.set("df","item_keywords");
  //设置高亮显示
  query.setHighlight(true);
   
  query.addHighlightField("item_title");
  query.setHighlightSimplePre("< em style=\"color:red\">");
  query.setHighlightSimplePost("</ em >");
//执行查询
  SearchResult searchResult = searchDao.search(query);
  //根据结果来计算商品总共多少页
  long recordCount=searchResult.getRecordCount();
  long pageCount=recordCount/rows;
  if (recordCount % rows > 0) {
   pageCount++;
  }
  searchResult.setPageCount(pageCount);
  searchResult.setCurPage((long) page);
   
   return searchResult;
  }
  
}

客户端通过输入商品来实现搜索功能:

controller层:

@Controller

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class SearchController {
  @Autowired
  private SearchService searchService;
   
  @RequestMapping("/search")
  public String search(@RequestParam("q")String queryString, @RequestParam(defaultValue="1")Integer page, Model model) {
   if (queryString != null) {
    try {
     queryString = new String(queryString.getBytes("iso8859-1"), "utf-8");
    } catch (UnsupportedEncodingException e) {
     e.printStackTrace();
    }
   }
   SearchResult searchResult = searchService.search(queryString, page);
   //向页面传递参数
   model.addAttribute("query", queryString);
   //model.addAttribute("totalPages", searchResult.getPageCount());
   model.addAttribute("itemList", searchResult.getItemList());
   model.addAttribute("page", page);
    
   return "search";
    
  }
}

service层:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Service
public class SearchServiceImpl implements SearchService {
   
  @Value("${SEARCH_BASE_URL}")
  private String SEARCH_BASE_URL;
  
  @Override
  public SearchResult search(String queryString, int page) {
   //这里需要的是连接+参数.这里每页显示的记录条数,可以传递也可以不用传递
   // 调用taotao-search的服务
   //查询参数
   Map< String , String> param = new HashMap<>();
   param.put("q", queryString);
   param.put("page", page + "");
   try {
    //调用服务
    String json = HttpClientUtil.doGet(SEARCH_BASE_URL, param);
    //把字符串转换成java对象
    TaotaoResult taotaoResult = TaotaoResult.formatToPojo(json, SearchResult.class);
    SearchResult result = (SearchResult) taotaoResult.getData();
    return result;
   /* if (taotaoResult.getStatus() == 200) {
      
    }*/
     
   } catch (Exception e) {
    e.printStackTrace();
    return null;
   }
   
  }
  
}

以上这篇利用solr实现商品的搜索功能(实例讲解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:

原文链接:https://www.cnblogs.com/fengli9998/p/6475970.html

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
    本课程全程使用目前比较流行的开发工具idea进行开发,涉及到目前互联网项目中最常用的高并发解决方案技术, 如dubbo,redis,solr,freemarker,activeMQ,springBoot框架,微信支付,nginx负载均衡,电商活动秒杀,springSecurity安全框架,FastDFS分布式文件服务器,还会涉及到代码生成器,   前台的技术有angularJS和BootStrap框架,此课程内容丰富实战性强,如果你还是传统项目的开发人员,那你学完本课程会有很大的收获,让你的薪资上涨,5K以上,让你完全感受到了互联网思维带来的高 并发解决方案的思路,如果你是开发的小白,建议你学完Spring,SpringMVC,MyBatis框架后再来学习本门课程,学完以后会让你完全体验到企业级开发的流程.在职开发人员学完后会让你的薪资更高,让你更了解互联网是如何解决高并发 学完SSM框架的同学就可以学习,能让你切身感受到企业级开发环境目标1:完成solr环境安装、中文分析器和业务域的配置目标2:会使用Spring Data Solr完成增删改查操作目标3:完成批量数据导入功能目标4:完成按关键字搜索功能目标5:实现考拉易购搜索结果高亮显示功能目标6:说出考拉易购搜索的业务规则和实现思路目标7:完成查询分类列表的功能目标8:完成缓存品牌和规格数据的功能目标9:完成显示品牌和规格数据的功能目标10:完成过滤条件构建的功能目标11:完成过滤查询的功能目标11:实现考拉易购价格区间筛选功能目标12:实现搜索结果分页功能目标13:理解多关键字搜索目标14:实现搜索结果排序功能目标15:实现隐藏品牌列表功能目标16:实现搜索页与首页对接功能目标17:完成更新索引库的功能

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值