Solr在Java项目中的使用

Solr在Java项目中的使用


Solr(全文搜索功能)的介绍,安装及配置
https://blog.csdn.net/qq_36521579/article/details/79711171


solrJ客户端

这里我们是ssm项目,用maven搭建项目,需要的jar包有
1. Spring的jar包
2. Springmvc的jar包。
3. Solrj的jar包。
4. Mybatis的jar包。

通过maven引入solr:

<!-- solr客户端 -->
        <dependency>
            <groupId>org.apache.solr</groupId>
            <artifactId>solr-solrj</artifactId>
            <version>4.10.3</version>
        </dependency>
把商品信息导入索引

使用java程序读取mysql数据库中的商品信息,然后创建solr文档对象,把商品信息写入索引库。
sql语句:
SELECT
a.id,a.title,a.sell_point,a.price,a.image,b.name,c.item_desc
from tb_item a
LEFT JOIN tb_item_cat b ON a.cid=b.id
LEFT JOIN tb_item_desc c on a.id=c.item_id
Dao层:
需要创建一个mapper接口+mapper映射文件。名称相同且在同一个目录下。
创建一个sql语句对应的pojo
pojo:Item类

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;

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getTitle() {
        return title;
    }
    public void setTitle(String title) {
        this.title = title;
    }
    public String getSell_point() {
        return sell_point;
    }
    public void setSell_point(String sell_point) {
        this.sell_point = sell_point;
    }
    public long getPrice() {
        return price;
    }
    public void setPrice(long price) {
        this.price = price;
    }
    public String getImage() {
        return image;
    }
    public void setImage(String image) {
        this.image = image;
    }
    public String getCategory_name() {
        return category_name;
    }
    public void setCategory_name(String category_name) {
        this.category_name = category_name;
    }
    public String getItem_des() {
        return item_des;
    }
    public void setItem_des(String item_des) {
        this.item_des = item_des;
    }

    @JsonIgnore
    public String[] getImages() {
        if (image != null) {
            String[] images = image.split(",");
            return images;
        }
        return null;
    }
}

ItemMapper

public interface ItemMapper {

    List<Item> getItemList();
}

Mapper文件

<?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>

Service层
功能:导入所有的商品数据。没有参数。从数据库中查询出所有的商品数据。创建一个SolrInputDocument对象,把对象写入索引库。
新建一个ItemService接口,ItemServiceimpl实现类
ItemService接口

public interface ItemService {
    TaotaoResult importAllItems();
}

ItemServiceimpl实现类

@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    private ItemMapper itemMapper;
    @Autowired
    private SolrServer solrServer;

    @Override
    public TaotaoResult importAllItems() {
        try {
            //查询商品列表
            List<Item> list = itemMapper.getItemList();
            //把商品信息写入索引库
            for (Item item : list) {
                //创建一个SolrInputDocument对象
                SolrInputDocument document = new SolrInputDocument();
                document.setField("id", item.getId());
                document.setField("item_title", item.getTitle());
                document.setField("item_sell_point", item.getSell_point());
                document.setField("item_price", item.getPrice());
                document.setField("item_image", item.getImage());
                document.setField("item_category_name", item.getCategory_name());
                document.setField("item_desc", item.getItem_des());
                //写入索引库
                solrServer.add(document);
            }
            //提交修改
            solrServer.commit();
        } catch (Exception e) {
            e.printStackTrace();
            return TaotaoResult.build(500, ExceptionUtil.getStackTrace(e));
        }
        return TaotaoResult.ok();
    }
}

这里用了
@Autowired
private SolrServer solrServer
所以我们在spring的配置文件中添加一个bean

<!-- 配置SolrServer对象 -->
<!-- 单机版 -->
<bean id="httpSolrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">
        <constructor-arg name="baseURL" value="http://192.168.25.154:8080/solr"></constructor-arg>
</bean>

Controller层
功能:发布一个rest形式的服务。调用Service的服务方法,把数据导入到索引库中,返回TaotaoResult。
Url:/search/manager/importall

@Controller
@RequestMapping("/search/manager")
public class ItemController {
    @Autowired
    private ItemService itemService;

    /**
     * 导入商品数据到索引库
     */
    @RequestMapping("/importall")
    @ResponseBody
    public TaotaoResult importAllItems() {
        TaotaoResult result = itemService.importAllItems();
        return result;
    }

接下来直接访问IP地址:8080/search/manager/importall就可以成功导入

分享一个可能发生的错误:

运行时可能找不到mapper的xml文件,也可能找不到resource下的文件
那么我们自动配置文件的位置就可以解决这种问题:
在pom.xml文件下的build标签下添加

        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>false</filtering>
            </resource>
        </resources>

搜索服务的发布

一、需求分析
http形式的服务。对外提供搜索服务是一个get形式的服务。调用此服务时需要查询条件,分页条件可以使用page(要显示第几页)、rows(每页显示的记录数)。返回一个json格式的数据。可以使用TaotaoResult包装一个商品列表转换成json。
请求的url:/search/query?q={查询条件}&page={page}&rows={rows}
返回的结果:TaotaoResult包装商品列表。
二、Dao层
分析:尽可能的做的通用一些。参数应该是SolrQuery。返回商品列表、查询结果总记录数
新建一个pojo,自行设置set,get方法,Item为上面已经定义过的商品信息类

public class SearchResult {

    //商品列表
    private List<Item> itemList;
    //总记录数
    private long recordCount;
    //总页数
    private long pageCount;
    //当前页
    private long curPage;
}

一个dao接口一个类

public interface SearchDao {

    SearchResult search(SolrQuery query) throws Exception;
}
@Repository
public class SearchDaoImpl implements SearchDao {

    @Autowired
    private SolrServer solrServer;

    @Override
    public SearchResult search(SolrQuery query) throws Exception {
        //返回值对象
        SearchResult result = new SearchResult();
        //根据查询条件查询索引库
        QueryResponse queryResponse = solrServer.query(query);
        //取查询结果
        SolrDocumentList solrDocumentList = queryResponse.getResults();
        //取查询结果总数量
        result.setRecordCount(solrDocumentList.getNumFound());
        //商品列表
        List<Item> itemList = new ArrayList<>();
        //取高亮显示
        Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();
        //取商品列表
        for (SolrDocument solrDocument : solrDocumentList) {
            //创建一商品对象
            Item item = new Item();
            item.setId((String) solrDocument.get("id"));
            //取高亮显示的结果
            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.setImage((String) solrDocument.get("item_image"));
            item.setPrice((long) solrDocument.get("item_price"));
            item.setSell_point((String) solrDocument.get("item_sell_point"));
            item.setCategory_name((String) solrDocument.get("item_category_name"));
            //添加的商品列表
            itemList.add(item);
        }
        result.setItemList(itemList);
        return result;
    }
}

三、Service层
功能:接收查询条件。查询条件及分页条件(page、rows),创建一个SolrQuery对象。指定查询条件、分页条件、默认搜索域、高亮显示。调用dao层执行查询。得到查询结果计算总页数。返回SearchResult对象。
一个Service层接口一个类

public interface SearchService {

    SearchResult search(String queryString, int page, int rows) throws Exception;
}
@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(page);
        return searchResult;
    }
}

四、Controller层

接收查询参数:查询条件、page、rows
调用Service执行查询返回一个查询结果对象。
把查询结果包装到TaotaoResult中返回,结果是json格式的数据。

如果查询条件为空,返回状态码:400,消息:查询条件不能为空。
Page为空:默认为1
Rows 为空:默认为60

@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);

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值