Lucene&Solr学习笔记之四使用SolrJ管理索引库

937

4. 使用SolrJ管理索引库

4.1 什么是solrJ

SolrJ是访间Solr服务的java客户端,提供索引和搜索的请求方法,SolrJ通常在嵌入在业务系统中,通过SolrJAPI接口操作Solr服务如下图:
SolrJ请求solr服务.png

4.2 导入SolrJ所需jar包

solr目录下的dist目录中导入下图jar包
在这里插入图片描述

4.3 SolrJ管理索引

首先,SolrJ管理索引是通过服务的方式,所以需要一个api,为搭建的solr服务器的基地址

http://localhost:8080/solr/collection1

注意:该地址不能写成:http://localhost:8080/solr/index.html#/collection1也不能写成http://localhost:8080/solr/index.html/collection1,collection1是需要操作的Core名称

为了下面的操作演示方便,提取一些公共代码:

/**
 * solr服务的基地址
 */
private static final String BASE_URL = "http://localhost:8080/solr/collection1";

/**
 * @Description: solr7已经删除了HttpSolrClient的构造方法创建SolrClient,需要使用Builder来构建
 * @param: @return      
 * @return: HttpSolrClient      
 * @throws
 */
public static HttpSolrClient getSolrClient(){
    /*
     * 设置连接的超时时间
     * .withConnectionTimeout(10000)
     * .withSocketTimeout(60000)
     */
    return new HttpSolrClient.Builder(BASE_URL)
        .withConnectionTimeout(10000)
        .withSocketTimeout(60000)
        .build();
}

4.3.1 SolrJ添加和更新索引

/**
 * @Description: 添加和更新索引,如果id不同为添加,id相同为更新
 * @throws IOException 
 * @throws SolrServerException
 * @param:       
 * @return: void      
 * @throws
 */
@Test
public void testAddIndex() throws SolrServerException, IOException{
    //单机版,通过get获取SolrClient
    SolrClient solrClient = getSolrClient();

    //添加时可以不指定id,solr会默认使用自己添加id例如:0be216be-de68-43b5-8917-a01e59936ce4
    //如果指定了id,在solr记录中存在就会更新信息,并且是真的更新,id还是原来那个
    SolrInputDocument document = new SolrInputDocument();
    //document.addField("id", "0be216be-de68-43b5-8917-a01e59936ce4");
    document.addField("product_name", "牛皮糖");

    solrClient.add(document);
    solrClient.commit();
}

4.3.2 SolrJ删除索引

@Test
public void testDelete() throws SolrServerException, IOException{
    SolrClient solrClient = getSolrClient();

    //根据id删除
    //solrClient.deleteById("0be216be-de68-43b5-8917-a01e59936ce4");

    //根据条件删除
    solrClient.deleteByQuery("product_name:牛皮");

    solrClient.commit();
}

4.3.3 SolrJ查询索引

/**
 * @Description: 使用   MapSolrParams 查询
 * @param: @throws SolrServerException
 * @param: @throws IOException      
 * @return: void      
 * @throws
 */
@Test
public void testMapSolrParams() throws SolrServerException, IOException{
    SolrClient solrClient = getSolrClient();

    Map<String,String> map = new HashMap<>();
    //指定查询关键词,只推荐写一个q,如果还有其他条件使用过滤条件
    map.put("q", "product_name:黑色");


    //fl:指定需要查询的域名称,则默认查询全部域
    //map.put("fl", "id, product_name,product_price");


    //指定排序:asc升序, desc降序
    //map.put("sort", "product_price asc");


    /*
	 * 使用过滤条件查询:
	 * 例如下面:查询价格小于100为[* TO 100],TO必须要是大写,
	 * 查询价格大于100的[100 TO *],[]表示包含,不包含使用{}
	 * 例如{],表示前包后不包
	 */
    //map.put("fq", "product_price:[* TO 100]");
    //map.put("fq", "product_price:[100 TO *]");
    //map.put("fq", "product_shop_name:旗舰店");

    //使用rows指定查询多少行,还可以指定start表示从查询结果的第几条开始选取指定条数,就是分页
    //map.put("rows", "1");

    /*
	 * 指定默认搜索域
	 * 如果搜索时没有指定搜索域则默认搜索这里指定的域
	 */
    map.put("df", "product_name");

    SolrParams solrParams = new MapSolrParams(map);
    QueryResponse queryResponse = solrClient.query(solrParams);
    System.out.println(queryResponse);
}

/**
 * @Description: 使用 SolrQuery 查询
 * @param: @throws SolrServerException
 * @param: @throws IOException      
 * @return: void      
 * @throws
 */
@Test
public void testSolrQuery() throws SolrServerException, IOException{
    SolrClient solrClient = getSolrClient();
    //关键词 过滤条件  排序 分页 开始行 每页数 高亮 默认域 只查询指定域
    SolrQuery solrQuery = new SolrQuery();
    //设置关键词,指定了默认域可以直接写关键词,等同于solrQuery.setQuery("product_name:衣服")
    solrQuery.set("q", "衣服");

    //设置过滤条件
    solrQuery.set("fq", "product_price:[* TO 100]");

    //添加排序条件
    solrQuery.addSort("product_price", ORDER.desc);

    //分页
    solrQuery.setStart(5);
    solrQuery.setRows(10);

    //设置默认域
    solrQuery.set("df", "product_name");

    //查询指定域,与上面一样key为fl,值为需要查询的域名称,这里省略不写了

    //高亮,打开高亮开关,设置高亮前缀和后缀即可使用高亮,此功能solr自带,但是高亮的结果和查询结果不再一个容器需要单独获取
    solrQuery.setHighlight(true);
    solrQuery.setHighlightSimplePre("<color style='color:red'>");
    solrQuery.setHighlightSimplePost("</color>");

    //执行查询
    QueryResponse queryResponse = solrClient.query(solrQuery);

    //获取高亮结果,最外层Map的K为id,V为Map,第二层Map,K为域名称,V为list
    Map<String,Map<String,List<String>>> hightLightMap = queryResponse.getHighlighting();

    //文档结果集
    SolrDocumentList solrDocumentList = queryResponse.getResults();
    //总条数
    Long totalCount = solrDocumentList.getNumFound();
    System.out.println("totalCount:" + totalCount);
    for(SolrDocument document : solrDocumentList){
        //System.out.println(document);

        //获取高亮文档
        Map<String,List<String>> fieldMap = hightLightMap.get(document.get("id"));
        //高亮的内容是搜索的域这里是默认域product_name,且获得的List只有product_name的值
        List<String> productNameList = fieldMap.get("product_name");
        System.out.println(productNameList.get(0));

    }
}

5. 案例

5.1 系统架构

案例架构图.png
这个案例不写商品修改了,所以mysql暂时不需要,如果设计到商品添加更新或者删除,需要同时维护数据库和Solr索引。

代码见资料:

百度网盘链接:https://pan.baidu.com/s/15V_UMGhsP6PDsdYwTi9C0w
提取码:u7zk