• Solr 09


    1 SolrJ是什么

    说明: SolrJ是访问Solr服务的Java客户端程序, 提供了索引和搜索的请求方法.

    SolrJ通常嵌入在业务系统中, 通过SolrJ的API接口操作Solr服务, 流程如下图:
    图片

    2 SolrJ对索引的CRUD操作

    使用SolrJ访问Solr服务, 完成索引的增、删、改、查操作.

    2.1 创建Maven工程(打包方式选择为jar)

    图片

    2.2 配置pom.xml文件, 加入SolrJ的依赖

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <packaging>jar</packaging>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <!-- solrj版本 -->
            <solrj.version>4.10.4</solrj.version>
            <!-- log4j日志版本 -->
            <slf4j.version>1.7.7</slf4j.version>
            <log4j.version>1.2.17</log4j.version>
            <!-- jcl版本 -->
            <jcl.version>1.7.6</jcl.version>
            <junit.version>4.12</junit.version>
        </properties>
    
        <dependencies>
            <!-- solrj依赖 -->
            <dependency>
                <groupId>org.apache.solr</groupId>
                <artifactId>solr-solrj</artifactId>
                <version>${solrj.version}</version>
            </dependency>
            <!-- log4j日志包 -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>${log4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-api</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>${slf4j.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>jcl-over-slf4j</artifactId>
                <version>${jcl.version}</version>
            </dependency>
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>jul-to-slf4j</artifactId>
                <version>${jcl.version}</version>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
        
    </project>
    

    2.3 添加和修改索引

    说明: Solr是根据id域(唯一约束)执行索引的添加(或更新)的:
    先根据id域执行查询, 查询到执行更新; 查询不到则执行添加.

    步骤:

    (1) 创建HttpSolrServer对象, 连接Solr服务;
    (2) 创建文档对象(SolrInuptDocument);
    (3) 使用HttpSolrServer对象, 执行添加(或更新);
    (4) 提交.

    /**
     * 添加与修改索引
     */
    @Test
    public void testSaveAndUpdateIndex() throws Exception {
        // 1. 创建HttpSolrServer对象, 连接Solr服务
        // 参数baseURL: 指定Solr的服务地址
        HttpSolrServer server = new HttpSolrServer("http://127.0.0.1:7070/solr");
        
        // 2. 创建文档对象(SolrInputDocument)
        SolrInputDocument document = new SolrInputDocument();
        // 在Solr中, id域是必需的
        document.addField("id", "9527");
        // 先设置如下值: 
        // document.addField("name", "solr solrj");
        // 再次设置, 测试更新索引 -- 如果存在则更新, 不存在则添加
        document.addField("name", "solr123 solrj");
        
        // 3. 使用HttpSolrServer对象, 执行添加(或更新)
        server.add(document);
        // 4. 提交更新
        server.commit();
    }
    
    图片

    2.4 删除索引

    (1) 根据id删除索引, 步骤为:

    ① 创建HttpSolrServer对象, 连接Solr服务;
    ② 使用HttpSolrServer对象, 执行删除;
    ③ 提交.

    /**
     * 根据id删除索引
     */
    @Test
    public void testDeleteIndexById() throws SolrServerException, IOException {
        // 1. 创建HttpSolrServer对象, 连接Solr服务
        // 参数baseURL: 指定Solr的服务地址
        HttpSolrServer server = new HttpSolrServer("http://127.0.0.1:7070/solr");
        
        // 2. 使用HttpSolrServer对象, 执行删除
        server.deleteById("9527");
        
        // 3. 提交
        server.commit();
    }
    

    (2) 根据条件删除索引, 步骤为:

    ① 创建HttpSolrServer对象, 连接solr服务;
    ② 使用HttpSolrServer对象, 执行删除;
    ③ 提交.

    /**
     * 根据条件删除索引
     */
    @Test
    public void testDeleteIndexByQuery() throws Exception {
        // 1. 创建HttpSolrServer对象, 连接Solr服务
        HttpSolrServer server = new HttpSolrServer("http://127.0.0.1:7070/solr");
        
        // 2. 使用HttpSolrServer对象, 执行删除
        server.deleteByQuery("name: solr");
        
        // 3. 提交更新
        server.commit();
    }
    

    2.5 查询索引

    查询步骤:

    (1) 创建HttpSolrServer对象, 连接Solr服务;
    (2) 创建查询对象(SolrQuery);
    (3) 使用HttpSolrServer对象, 执行查询, 返回查询响应对象QueryResponse;
    (4) 使用QueryResponse对象, 获取查询的结果集SolrDocumentList;
    (5) 处理结果集.

    /**
     * 查询索引
     */
    @Test
    public void testQueryIndex() throws Exception {
        // 1. 创建HttpSolrServer对象, 连接Solr服务
        HttpSolrServer server = new HttpSolrServer("http://127.0.0.1:7070/solr");
        
        // 2. 创建查询对象(Query)
        // : 表示查询所有
        SolrQuery query = new SolrQuery(":");
        
        // 3.使用HttpSolrServer对象, 执行查询, 返回查询响应对象QueryResponse
        QueryResponse queryResponse = server.query(query);
        
        // 4.使用QueryResponse对象, 获取查询的结果集SolrDocumentList
        SolrDocumentList results = queryResponse.getResults();
        
        // 5.处理结果集
        // 打印查询到的结果数量
        System.out.println("结果数量: " + results.getNumFound());
        for (SolrDocument doc : results) {
            System.out.println("= = = = = = = = = = = = = = = = = = =");
            // 打印id域和name域
            System.out.println("id: " + doc.get("id"));
            System.out.println("name: " + doc.get("name"));
        }
    }
    
    图片

    3 SolrJ的查询方案

    3.1 实现步骤

    (1) 创建HttpSolrServer对象, 连接Solr服务;
    (2) 创建查询对象(SolrQuery), 设置查询条件;
    (3) 使用HttpSolrServer对象, 执行查询, 返回查询响应对象(QueryResponse);
    (4) 使用QueryResponse对象, 获取查询数据;
    (5) 处理结果集.

    3.2 示例代码

    /**
     * SolrJ高级查询
     */
    @Test
    public void queryIndexSenior() throws Exception {
        // 1. 创建HttpSolrServer对象, 连接Solr服务
        // 参数baseURL:指定Solr的服务地址
        HttpSolrServer solrServer = new HttpSolrServer("http://127.0.0.1:7070/solr/collection1");
        
        // 2. 创建查询对象(SolrQuery), 设置查询条件
        SolrQuery solrQuery = new SolrQuery();
        // 2.1 设置查询表达式
        solrQuery.setQuery("花儿朵朵");
        // 2.2 设置过滤条件
        solrQuery.setFilterQueries("product_price:[* TO 20]");
        // 2.3 设置排序sort
        solrQuery.setSort("product_price", ORDER.desc);
        // 2.4 设置分页: start, rows
        solrQuery.setStart(0);
        solrQuery.setRows(10);
        // 2.5 设置显示的域列表
        solrQuery.setFields("id", "product_name", "product_price", "product_catalog_name");
        // 2.6 设置默认的搜索域
        solrQuery.set("df", "product_name");
        // 2.7 设置响应格式
        solrQuery.set("wt", "json");
        
        // 2.8 设置高亮显示
        solrQuery.setHighlight(true);  // 开启高亮显示
        // 或者: solrQuery.setParam("hl", "true");
        solrQuery.addHighlightField("product_name");  // 添加高亮显示的域
        solrQuery.setHighlightSimplePre("<font color='red'>");  // 设置高亮显示的HTML标签的前缀
        solrQuery.setHighlightSimplePost("<font>");  // 设置高亮显示的HTML标签的后缀
        
        // 2.9 设置分片统计facet
        solrQuery.setFacet(true);  // 开启分片统计
        solrQuery.addFacetField("product_catalog_name");  // 添加分片统计的域
        
        // 3. 使用HttpSolrServer对象, 执行查询, 返回查询相应对象
        QueryResponse queryResponse = solrServer.query(solrQuery);
        
        /* 处理结果集
        NamedList list = (NamedList) queryResponse.getResponse().get("highlighting");
        for (int i = 0; i < list.size(); i++) {
            System.out.println("id=" + list.getName(i) + "高亮字段: " + list.getVal(i));
        }
        */
        
        // 4. 使用QueryResponse对象, 获取查询数据
        // 4.1 获取查询结果集
        SolrDocumentList results = queryResponse.getResults();
        // 4.2 获取高亮显示数据
        // 第一个Map的key是文档的id, 第二个Map的key是高亮显示的字段名, 第二个Map中的value是处理过的高亮显示结果集, 类型为List<String>
        Map<String, Map<String, List<String>>> hlMap = queryResponse.getHighlighting();
        // 4.3 获取分片统计数据
        List<FacetField> facetFields = queryResponse.getFacetFields();
        
        // 6. 处理结果集
        System.out.println("结果数量:" + results.getNumFound());
        for (SolrDocument doc : results) {
            System.out.println("= = = = = = = = = = = = = = = = = = =");
            // id, product_name, product_price, product_catalog_name
            // 获取商品id
            String pid = doc.get("id").toString();
            // 获取商品名称: 先从高亮显示结果中获取, 若没有获取到, 再从doc中获取
            String pname = "";
            List<String> list = hlMap.get(pid).get("product_name");
            if (null != list && list.size() > 0) {
                pname = list.get(0);
            } else {
                pname = doc.get("product_name").toString();
            }
            
            // 获取商品价格
            String pprice = doc.get("product_price").toString();
            // 获取商品的分类名称
            String pcatalogName = doc.get("product_catalog_name").toString();
            
            // 输出结果
            System.out.println("商品id: " + pid);
            System.out.println("商品名称: " + pname);
            System.out.println("商品价格: " + pprice);
            System.out.println("商品分类名称: " + pcatalogName);
        }
    }
    

    3.3 代码搜索结果

    图片

    3.4 查看分片统计数据

    // 5. 处理分片统计数据(如有)
    System.out.println("分片统计数据 = = = = = = = = = = = Begin");
    for (FacetField field : facetFields) {
        System.out.println("统计域名称: " + field.getName() + " , 统计到的组数量: " + field.getValueCount());
        // 查看各个组的数量
        List<Count> values = field.getValues();
        for (Count count : values) {
            System.out.println("组名称: " + count.getName() + " , 该组的数量: " + count.getCount());
        }
    }
    System.out.println("分片统计数据 = = = = = = = = = = = End");
    

    3.5 分片统计数据结果

    图片

    版权声明

    作者: 马瘦风

    出处: 博客园 马瘦风的博客

    您的支持是对博主的极大鼓励, 感谢您的阅读.

    本文版权归博主所有, 欢迎转载, 但请保留此段声明, 并在文章页面明显位置给出原文链接, 否则博主保留追究相关人员法律责任的权利.

  • 相关阅读:
    ★寒门再难出贵子?太现实了!【下】
    ★寒门再难出贵子?太现实了!【下】
    ★寒门再难出贵子?太现实了!【下】
    ★寒门再难出贵子?太现实了!!【上】
    ★寒门再难出贵子?太现实了!!【上】
    ★寒门再难出贵子?太现实了!!【上】
    Linux简介
    UTF-8编码规则【转】
    UTF-8编码规则【转】
    UTF-8编码规则【转】
  • 原文地址:https://www.cnblogs.com/shoufeng/p/9842902.html
Copyright © 2020-2023  润新知