美文网首页
用Solr实现后台搜索[笔记]

用Solr实现后台搜索[笔记]

作者: lhsjohn | 来源:发表于2019-03-03 23:05 被阅读0次

今天做了一个搜索的小案例。使用solr服务实现后台的搜索功能,并在前台展示出搜索结果。

下面大体说一下自己的实现方案

1.png

1.首先是完成自己solr服务器的配置

进入linux上配置的 solr-tomcat2->solr-home->collection1->conf
用vim 修改里面的schema.xml文件搜索相关域的信息。

在这里我加入了下面的配置


<fieldType name="text_ik" class="solr.TextField">
  <analyzer class="org.wltea.analyzer.lucene.IKAnalyzer"/>
</fieldType>
<field name="stu_usr_name" type="text_ik" indexed="true" stored="true"/>
<field name="stu_email" type="text_ik" indexed="true" stored="true"/>
<field name="stu_phone"  type="string" indexed="true" stored="true"/>

<field name="ent_usr_name" type="string" indexed="false" stored="true" />
<field name="ent_phone" type="string" indexed="true" stored="true" />



<field name="cmd_name" type="text_ik" indexed="true" stored="true"/>
<field name="cmd_detail" type="text_ik" indexed="true" stored="true"/>
<field name="cmd_name" type="text_ik" indexed="true" stored="true"/>
<field name="cmd_detail" type="text_ik" indexed="true" stored="true"/>


<field name="item_keywords" type="text_ik" indexed="true" stored="false" multiValued="true"/>
<copyField source="cmd_name" dest="item_keywords"/>
<copyField source="cmd_detail" dest="item_keywords"/>
<copyField source="cmd_type" dest="item_keywords"/>


2.后台封装了搜索结果类SearchResult


package com.ffGarden.pojo;

import java.util.List;

/**
 * 搜索返回结果
 * 
 * @author lihuashuo
 *
 */
public class SearchResult {
    
    private List<ItgCommodity> itgCommodityList;
    private List<Enterprise> enterpriseList;
    private List<StuAccount> stuAccountList;

    public List<ItgCommodity> getItgCommodityList() {
        return itgCommodityList;
    }

    public void setItgCommodityList(List<ItgCommodity> itgCommodityList) {
        this.itgCommodityList = itgCommodityList;
    }

    public List<Enterprise> getEnterpriseList() {
        return enterpriseList;
    }

    public void setEnterpriseList(List<Enterprise> enterpriseList) {
        this.enterpriseList = enterpriseList;
    }

    public List<StuAccount> getStuAccountList() {
        return stuAccountList;
    }

    public void setStuAccountList(List<StuAccount> stuAccountList) {
        this.stuAccountList = stuAccountList;
    }

    @Override
    public String toString() {
        return "SearchResult [itgCommodityList=" + itgCommodityList + ", enterpriseList=" + enterpriseList
                + ", stuAccountList=" + stuAccountList + "]";
    }
  
    
    
    
}



3通过SpringBoot的单元测试的方式完成了对索引库 的添加。

这里有坑,如果不采用SpringBootTest,而是只是使用Junit单元测试的方式,你会发现@Autowired的方式自动注入的属性是空值,所以一直报空指针异常。



package com.ffGarden.solr;

import java.io.IOException;
import java.util.List;

import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrServer;
import org.apache.solr.common.SolrInputDocument;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.web.bind.annotation.RestController;

import com.ffGarden.FfGardenSpringbootApplication;
import com.ffGarden.pojo.Enterprise;
import com.ffGarden.pojo.ItgCommodity;
import com.ffGarden.pojo.StuAccount;
import com.ffGarden.service.EnterpriseService;
import com.ffGarden.service.ItgCommodityService;
import com.ffGarden.service.StuAccountService;
import com.ffGarden.service.impl.ItgCommodityServiceImpl;
@SpringBootTest(classes = FfGardenSpringbootApplication.class,webEnvironment =SpringBootTest.WebEnvironment.RANDOM_PORT)
@RunWith(SpringRunner.class)
public class AddDocumet {
    
    @Autowired
    private ItgCommodityService itgCommodityServer;
    
    @Autowired
    private EnterpriseService enterpriseService;
    
    @Autowired
    private StuAccountService stuAccountService;

    @Autowired
    private  SolrServer solrServer;

    
    /**
     * 将商品信息记录导入索引库
     * @throws Exception
     */
    @Test
    public void addItgCommodityDocument() throws Exception {
        //ItgCommodityService itgCommodityServer = new ItgCommodityServiceImpl();
        //SolrServer solrServer = new HttpSolrServer("http://192.168.1.128:8080/solr/collection1");
        // 先从数据库中搜索所有记录
        List<ItgCommodity> ItgCommoditylist = itgCommodityServer.getAllCommodities();
        // 迭代导入索引库
        for (ItgCommodity item : ItgCommoditylist) {
            // 创建一个文档对象
            SolrInputDocument document = new SolrInputDocument();
            // 向文档对象中添加域
            document.addField("id", "cmd"+item.getItgNumber());
            document.addField("cmd_name", item.getCmdName());
            document.addField("cmd_detail", item.getCmdDetail());
             document.addField("cmd_prise", item.getCmdPrise().intValue());
            document.addField("cmd_type", item.getCmdType());
            document.addField("cmd_integral", item.getNeedIntegral());
            // 写入索引库
            solrServer.add(document);
        }
        // 提交
          solrServer.commit();
    }
    
    /**
     * 将学生账户记录导入索引库
     * @throws Exception
     */
    @Test
    public void addStuAccountDocument() throws Exception {
        //先从数据库中搜索所有的学生账户记录
        List<StuAccount> stuAccountList = stuAccountService.getAllStuAccounts();
        //迭代导入索引库
        for(StuAccount item:stuAccountList) {
            //创建一个文档对象
            SolrInputDocument document = new SolrInputDocument();
            document.addField("id", "stu"+item.getStuNumber());
            document.addField("stu_phone", item.getStuPhone());
            document.addField("stu_usr_name", item.getStuUsrName());
            document.addField("stu_email", item.getStuEmail());
            //写入索引库
            solrServer.add(document);
        }
        //提交
        solrServer.commit();
        
    }
    
    /**
     * 将企业账户记录导入索引库
     */
    @Test
    public void addEnterpriseDocument() throws Exception {
        
        //从数据库中获取企业列表
        List<Enterprise> enterpriseList = enterpriseService.getEnterpriseList();
        //迭代导入索引库
        for(Enterprise item : enterpriseList) {
            SolrInputDocument document = new SolrInputDocument();
            document.addField("id", "ent"+item.getEntNumber());
            document.addField("ent_usr_name", item.getEntUsrName());
            document.addField("ent_phone", item.getEntPhone());
            document.addField("ent_email", item.getEntEmail());
            //写入索引库
            solrServer.add(document);
        }
        //提交
        solrServer.commit();
            
    }
    
        
}


下面写了三个搜索的方法,完成设置条件的搜索,分别来搜索商品、企业以及学生用户信息。


/**
     * 从索引库根据条件查询学生账户
     * 
     * @param query
     * @return
     * @throws Exception
     */

    public List<StuAccount> searchStuAccount(SolrQuery query) throws Exception {
        // 根据查询条件查询索引库
        QueryResponse queryResponse = solrServer.query(query);
        // 取查询结果总记录数
        SolrDocumentList solrDocumentList = queryResponse.getResults();

        // 创建一个学生账户列表对象
        List<StuAccount> accountList = new ArrayList<>();
        // 取学生列表
        // 取高亮后的结果
        Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
        for (SolrDocument solrDocument : solrDocumentList) {
            // 取学生账户的信息

            StuAccount account = new StuAccount();
            // 获取doc 的id 在这里例如是stu1
            String docId = (String) solrDocument.get("id");
            // 截取id 把前三位的stu 截取掉,这里变成"1"

            String stuId = docId.substring(3);
            account.setStuNumber(Integer.valueOf(stuId));
            account.setStuUsrName((String) solrDocument.get("stu_usr_name"));
            account.setStuEmail((String) solrDocument.get("stu_email"));
            account.setStuPhone((String) solrDocument.get("stu_phone"));

            // 取高亮结果
            List<String> list = highlighting.get(solrDocument.get("id")).get("stu_usr_name");
            String stuName = "";
            if (list != null && list.size() > 0) {
                stuName = list.get(0);
            } else {
                stuName = (String) solrDocument.get("stu_usr_name");
            }
            account.setStuUsrName(stuName);

            // 添加到商品列表
            accountList.add(account);

        }

        return accountList;

    }

    /**
     * 从索引库根据条件查询商品信息
     * 
     * @param query
     * @return
     * @throws Exception
     */
    public List<ItgCommodity> searchItgCommodity(SolrQuery query) throws Exception {
        // 根据查询条件查询索引库
        QueryResponse queryResponse = solrServer.query(query);
        // 取查询结果总记录数
        SolrDocumentList solrDocumentList = queryResponse.getResults();

        // 创建一个商品列表对象
        List<ItgCommodity> itemList = new ArrayList<>();
        // 取商品列表
        // 取高亮后的结果
        Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
        for (SolrDocument solrDocument : solrDocumentList) {
            // 取商品的信息
            ItgCommodity item = new ItgCommodity();
            String docId = (String) solrDocument.get("id");
            // 截取id 把前三位的stu 截取掉,这里变成"1"
            String cmdId = docId.substring(3);
            item.setItgNumber(Integer.valueOf(cmdId));
            item.setCmdDetail((String) solrDocument.get("cmd_detail"));
            item.setCmdType((String) solrDocument.get("cmd_type"));
            item.setCmdPrise(BigDecimal.valueOf((long) solrDocument.get("cmd_prise")));
            item.setNeedIntegral((int) (long) solrDocument.get("cmd_integral"));

            // 取高亮结果
            List<String> list = highlighting.get(solrDocument.get("id")).get("cmd_name");
            String cmdName = "";
            if (list != null && list.size() > 0) {
                cmdName = list.get(0);
            } else {
                cmdName = (String) solrDocument.get("cmd_name");
            }

            item.setCmdName(cmdName);
            // 添加到商品列表
            itemList.add(item);

        }

        return itemList;

    }

    /**
     * 从索引库根据条件查询企业信息
     * 
     * @param query
     * @return
     * @throws Exception
     */
    public List<Enterprise> searchEnterprise(SolrQuery query) throws Exception {
        // 根据查询条件查询索引库
        QueryResponse queryResponse = solrServer.query(query);
        // 取查询结果总记录数
        SolrDocumentList solrDocumentList = queryResponse.getResults();

        // 创建一个商品列表对象
        List<Enterprise> entList = new ArrayList<>();
        // 取商品列表
        // 取高亮后的结果
        Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
        for (SolrDocument solrDocument : solrDocumentList) {

            // 取企业的信息
            Enterprise enterprise = new Enterprise();
            // 获取doc 的id 在这里例如是stu1
            String docId = (String) solrDocument.get("id");
            // 截取id 把前三位的stu 截取掉,这里变成"1"
            String entId = docId.substring(3);
            enterprise.setEntNumber(Integer.valueOf(entId));
            enterprise.setEntEmail((String) solrDocument.get("ent_email"));
            enterprise.setEntPhone((String) solrDocument.get("ent_phone"));

            // 取高亮结果
            List<String> list = highlighting.get(solrDocument.get("id")).get("ent_usr_name");
            String cmdName = "";
            if (list != null && list.size() > 0) {
                cmdName = list.get(0);
            } else {
                cmdName = (String) solrDocument.get("ent_usr_name");
            }
            enterprise.setEntUsrName(cmdName);
            // 添加到商品列表
            entList.add(enterprise);

        }

        return entList;

    }




最后是Controller的代码

@RequestMapping(value = "/searchItems", method = RequestMethod.GET)
    @ResponseBody
    public EyeJSONResult searchItems(@RequestParam(value = "content", required = true) String content)
            throws Exception {

        // 创建一个SolrQuery对象
        SolrQuery query = new SolrQuery();
        // 设置查询条件
        query.setQuery(content);
        // 设置默认搜索域
        query.set("df", "cmd_name");
        // 设置高亮显示
        query.setHighlight(true);
        query.addHighlightField("cmd_name");
        query.setHighlightSimplePre("<em style=\"color:red\">");
        query.setHighlightSimplePost("</em>");
        // 执行查询
        List<ItgCommodity> itemList = searchItgCommodity(query);
        // 更换搜索域,搜索学生用户
        query.set("df", "stu_usr_name");
        query.addHighlightField("stu_usr_name");
        List<StuAccount> stuAccountList = searchStuAccount(query);
        // 更换搜索域,搜索企业用户
        query.set("df", "ent_usr_name");
        query.addHighlightField("ent_usr_name");
        List<Enterprise> enterpriseList = searchEnterprise(query);
        // 创建搜索结果对象
        SearchResult result = new SearchResult();
        result.setStuAccountList(stuAccountList);
        result.setItgCommodityList(itemList);
        result.setEnterpriseList(enterpriseList);
        // 打印查询结果
        // System.out.println(itemList.toString());
        // System.out.println("1111111111111111111");
        // System.out.println(content);
        // SolrJUtils.queryIndex(content);
        return EyeJSONResult.ok(result);
    }




最后看一下前端的几处关键的实现

store 里面的commodity.js

import { default as api } from '../../util/api'

const commodity = {
    state:{
        cmdNumber: 0,
        commodityDetail:{},
        orderNumber: -1,
        sumPrice: -1,
        searchContent: ""
    },
    mutations: {
        DETAIL:(state, commodityDetail) => {
            state.cmdNumber = commodityDetail.cmdNumber
            state.commodityDetail = commodityDetail
        },
        ORDERNUMBER:(state, orderNumber) => {
            state.orderNumber = orderNumber;
        },
        SUMPRICE:(state, sumPrice) => {
            state.sumPrice = sumPrice;
        },
        SEARCH:(state,searchContent)=>{
            state.searchContent = searchContent
        }
    },
    actions:{
        getCommodityDetail({ commit, state }, searchContent) {
            return new Promise((resolve, reject) => {
                api({
                    url: "/search/searchItems",
                    method: "get",
                    params: {
                        content: searchContent
                    }
                }).then(res => {
                    state.commodityDetail = res.data;
                    resolve(res);
                }).catch(err => {
                    reject(err)
                })
            })

        }
    },
    }



export default commodity


getter.js


import commodity from "./modules/commodity";

const getters = {
    receiptInfo:state => state.enterprise.receiptInfo,
    commodityDetail:state => state.commodity.commodityDetail,
    cmdNumber:state => state.commodity.cmdNumber,
    orderNumber:state => state.commodity.orderNumber,
    sumPrice:state => state.commodity.sumPrice,
    role:state => state.user.role,
    userNumber:state => state.user.userNumber,
    searchContent:state => state.commodity.searchContent
}

export default getters

 doSearch() {
  
      this.$store.commit("SEARCH",this.searchContent)
      this.$router.push("/studentSearch")
    }


computed: {
    ...mapGetters(["searchContent", "commodityDetail"])
  },
  created() {
    this.api({
      url: "/search/searchItems",
      method: "get",
      params: {
        content: this.searchContent
      }
    }).then(res=>{
       this.enterpriseList = res.data.enterpriseList;
       this.stuAccountList = res.data.stuAccountList;
       this.comodityList = res.data.itgCommodityList;
       //console.log(res.data)
    })

    //this.getCommodityList();
  }


作者:lhsjohn

相关文章

  • 用Solr实现后台搜索[笔记]

    今天做了一个搜索的小案例。使用solr服务实现后台的搜索功能,并在前台展示出搜索结果。 下面大体说一下自己的实现方...

  • ActiveMQ在分布式项目中的实际应用

    具体需求: 后台添加商品后,需要执行两个操作: 同步索引库(商品搜索使用了Solr实现) 生成静态页面(使用fre...

  • 搜索引擎——Solr安装、配置

    搜索引擎——Solr安装、配置 什么是solr? Solr是如何实现全文检索的呢? 索引流程:solr客户端(浏览...

  • web整合Solr

    1..Solr案例实战 1.1.需求 使用Solr实现电商网站中商品信息搜索功能,可以根据关键字、分类、价格搜索商...

  • 无标题文章

    一、启动solr 1.通过实现配置好的techproducts示例内核启动solr搜索服务器 ```bin/sol...

  • Solr搜索

    参见上文solr概述 - 简书 搜索 Solr搜索参数介绍 如图,solr基本的查询参数如上。 q搜索关键词q的值...

  • 微服务架构Day37-Dubbo之全文搜索

    Solr Solr是一个可扩展的,可部署,搜索,存储引擎,优化搜索大量以文本为中心的数据库Solr是开源搜索平台,...

  • solr

    何为solr solr是java搜索引擎Lucene的更高一层封装,通过webapp服务器实现可视化界面,方便使用...

  • 如何使用MapReduce构建Solr索引

    Solr 是什么? Solr 是一个开源的企业级搜索服务器,底层使用易于扩展和修改的 Java 来实现。服务 器通...

  • 如何设置solr搜索的关键字在回显页面高亮

    个人学习以做笔记记录,在搜索solr时对关键字进行高亮显示 /** * 根据关键字搜索列表 * @param ke...

网友评论

      本文标题:用Solr实现后台搜索[笔记]

      本文链接:https://www.haomeiwen.com/subject/zwjvuqtx.html