码迷,mamicode.com
首页 > 其他好文 > 详细

Solr06-SolrJ的使用及其高级查询

时间:2018-08-27 00:59:22      阅读:217      评论:0      收藏:0      [点我收藏+]

标签:result   通配   3.1   filter   getname   json   请求   管理   map   

目录

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">
    
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- solrj版本 -->
        <solrj.version>4.10.4</solrj.version>
        <!-- ...... --> 
    </properties>
    
    <dependencies>
        <!-- solrj依赖 -->
        <dependency>
            <groupId>org.apache.solr</groupId>
            <artifactId>solr-solrj</artifactId>
            <version>${solrj.version}</version>
        </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 删除索引

2.4.1 根据id删除索引

  1. 创建HttpSolrServer对象, 连接Solr服务;
  2. 使用HttpSolrServer对象, 执行删除;
  3. 提交.
/**
 * 根据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.4.2 根据条件删除索引

  1. 创建HttpSolrServer对象, 连接solr服务;
  2. 使用HttpSolrServer对象, 执行删除;
  3. 提交.
/**
 * 根据条件删除索引
 */
@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 Solr管理页面的查询

3.1 Solr管理页面的查询入口

选中需要查询的SolrCore, 然后在菜单栏选择[Query]:
技术分享图片

3.2 Solr查询输入框简介

  • select: 查询请求处理器.
    技术分享图片

  • q: query的简写, 指定查询表达式.
    技术分享图片
    *:*, 表示查询所有, 如:
    product_name:花儿朵朵, 表示product_name域中包含花儿朵朵.

  • fq: filter query的简写, 是一个数组, 可指定多个. 在q的查询结果中, 执行过滤 -- 前提: 需要指定q查询
    技术分享图片
    product_price:[* TO 20], 表示查询商品价格在20块钱以内, 包含20;
    product_price:[* TO 20}, 表示查询商品价格在20块钱以内, 不包含20.

  • sort: 指定搜索结果的排序.
    技术分享图片
    product_price desc -- 表示按照商品价格降序
    product_price asc -- 表示按照商品价格升序
    product_price desc, product_catalog asc -- 表示按商品价格降序, 按商品分类id升序(多个域排序, 以半角逗号分割)

  • start,rows: 指定搜索结果分页
    技术分享图片
    start: 结果记录起始数
    rows: 每一页显示记录数

  • fl: field list的简写, 指定搜索结果显示的域列表.
    技术分享图片
    id, product_name, product_price, product_catalog_name
    -- 表示显示商品Id, 商品名称, 商品价格, 商品类别名称

  • df: default field的简写, 指定默认搜索域 -- 只能指定一个.
    技术分享图片

  • wt: writer type的简写, 指定搜索结果数据的响应格式.
    (csv格式: 类似于记事本的格式.)
    indent: 缩进, 格式良好地显示查询结果;
    debugQuery: 打印查询的调试信息.
    技术分享图片

  • dismax、edismax: 查询解析器, 一般不选择. /select等使用的是标准查询解析器.

  • hl: high light的简写, 设置高亮显示. 高亮显示的field, 需要stored=true.
    技术分享图片

    hl.fl: 高亮显示的域的名称;
    hl.simple.pre: 高亮显示的HTML标签前缀;
    hl.simple.post: 高亮显示的HTML标签后缀;
    hl.requireFieldMatch: 默认为false, 若选中(为true), 则需要hl.fl指定字段, 查询结果才会高亮;
    hl.usePhraseHighlighter: 如果查询语句中含有引号括起来的短语, 那么只有完全匹配短语的内容才会高亮;
    hl.highlightMultiTerm: 默认为false, 若选中且hl.usePhraseHighlighter为true时, 如果使用通配符和模糊搜索, 那么会确保与通配符匹配的term才会高亮.

  • facet(扩展): 分组统计(分片统计), 如电商中的组合多条件搜索:
    技术分享图片

    facet查询设置界面:
    技术分享图片
    facet.query: 指定组内初始化统计条件
    facet.field: 指定分组统计的域的名称(通常使用分类域)
    facet.prefix: 指定组内过滤查询条件的前缀

  • spatial: 空间查询(经纬度)

  • spellcheck: 拼写检查, 即输入时的智能匹配

3.3 Solr管理页面的查询方案

说明: 使用SolrJ实现页面的查询效果, 要求参数和结果与页面一致.

  • 页面搜索条件:
    技术分享图片

  • 页面搜索结果:
    文档结果以及分组统计结果:
    技术分享图片

    高亮显示结果:
    技术分享图片

注意:

  1. 由上图可知, Solr在高亮查询时, 高亮结果集与正常结果集是分开返回的, 为了与正常结果集中的其他内容相匹配, 这里需要设置主键进行结果的关联.

  2. 另外, 对于multiValued=true的字段, 不要进行高亮设置 -- 它只会返回匹配高亮的值, 不能确定是何条数据.

  3. 也可通过HTTP请求的方式进行高亮设置, HTTP请求示例:

    http://localhost:7070/solr/select?q=product_name:花儿朵朵&hl=true&hl.fl=product_name&hl.simple.pre=<font color=‘red‘>&hl.simple.post=</font>

  4. 也可通过配置solrconfig.xml文件, 是默认搜索方案具有高亮功能: 在下配置.
    技术分享图片

4 SolrJ的查询方案

4.1 实现步骤

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

4.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);
    }
}

4.3 代码搜索结果

技术分享图片

4.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");

4.5 分片统计数据结果

技术分享图片

版权声明

作者: ma_shoufeng(马瘦风)

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

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

本文版权归博主所有, 欢迎转载, 但未经博主同意必须保留此段声明, 且在文章页面明显位置给出原文链接, 否则博主保留追究法律责任的权利.

Solr06-SolrJ的使用及其高级查询

标签:result   通配   3.1   filter   getname   json   请求   管理   map   

原文地址:https://www.cnblogs.com/shoufeng/p/9539608.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!