solr服务器的使用

19人阅读 评论(0) 收藏 举报
分类:

后期补充:

为什么要用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的字段。

<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
11
package com.taotao.search.mapper;
 
import java.util.List;
 
import com.taotao.search.pojo.Item;
 
public interface ItemMapper {
    List<item> getItemList();
 
}
</item>

  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"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<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
@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全文检索服务器搭建与基本使用介绍

本次将介绍solr全文检索服务器的搭建和基本使用,下面将从服务器搭建、schema配置、solrj与spring整合、solrj简单使用等几个方面介绍...
  • u012476983
  • u012476983
  • 2017-01-03 10:27:28
  • 1237

搜索学习--Solr服务器的搭建与使用

solr服务器的搭建与使用,我们尝试着建立一个索引.之前用过Lucene的同学应该知道,我们建立一个索引是需要Document和Field的,而这些Field呢,在Solr中可以在managed-sc...
  • qq_18860653
  • qq_18860653
  • 2017-07-04 09:39:43
  • 1025

Solr web服务器管理界面用法

solr web应用自带了管理界面,可以方便的查看系统状态,solr设置,分词检验,索引查询,增减核心(core)等 测试于:Solr 4.5.0 这里列举一些常用的比较重要的内容。 D...
  • Truong
  • Truong
  • 2015-09-16 13:53:46
  • 3067

windows系统下搭建solr6服务器

首先   我们需要下载solr,本次以solr6.2.1版本为例,目前监测到的最新版为6.3.0,版本选择可以根据自己的需要,下载地址为点击下载 然后   下载jdk,犹豫solr6是基于jdk8版本...
  • qinhGG
  • qinhGG
  • 2017-01-13 10:10:14
  • 1980

搜索引擎Solr环境搭建详解

Solr服务器采用java5开发的,是基于Lucene全文搜索的。 要想搭建Solr,首先进行java环境的配置,安装对应的jdk以及tomcat,在此就不多讲。 以下是在jdk1.7和tomcat1...
  • tjcyjd
  • tjcyjd
  • 2015-01-24 21:28:11
  • 14345

solr服务器搭建

Solr中国网址 http://www.solr.cc/blog/?page_id=1267 http://www.cnblogs.com/hoojo/archive/2011/10/21/222...
  • jakeswang
  • jakeswang
  • 2016-01-25 13:38:45
  • 1736

centos搭建的solr服务器

  • 2018年01月19日 10:02
  • 49B
  • 下载

solr入门之环境搭建-内嵌的jetty服务发布(单机版)

用内置的jetty服务部署solr~
  • hll814
  • hll814
  • 2016-05-12 22:52:15
  • 777

Solr 6.0 学习(一)环境搭建

准备工作: 目前最新版本6.0。下载solr 6.0:Solr6.0下载 JDK8 下载jdk1.8:jdk1.8【solr6.0是基于jdk8开发的】 tomcat8.0 下载:tomcat8 ##...
  • upxiaofeng
  • upxiaofeng
  • 2016-05-16 16:26:38
  • 7269

Solr部署及开发

  • 2014年12月03日 16:24
  • 11KB
  • 下载
    个人资料
    等级:
    访问量: 3642
    积分: 172
    排名: 104万+
    文章分类