Java中使用Solr(SolrJ的使用)

链式冰川
• 阅读 6762

1. 什么是SolrJ

SolrJ是访问Solr服务的java客户端,提供索引和搜索的请求方法,SolrJ通常在嵌入在业务系统中,通过SolrJ的API接口操作Solr服务。

2. 添加/更新/删除

根据业务需要我们一般会在schema.xml中自定义一套Field,如下是商品信息Field(和Bean对应):

<!--product-->
<field name="product_name" type="text_ik" indexed="true" stored="true"/>
<field name="product_price" type="float" indexed="true" stored="true"/>
<field name="product_picture" type="string" indexed="false" stored="true" />
<field name="product_description" type="text_ik" indexed="true" stored="false" />
<field name="product_catalog_name" type="string" indexed="true" stored="true" />
<field name="product_keywords" type="text_ik" indexed="true" stored="false"multiValued="true"/>
<copyField source="product_name" dest="product_keywords"/>
<copyField source="product_description" dest="product_keywords"/>

2.1 创建索引

// 创建索引,如果id存在则更新,如果id不存在则新建
@Test
public void testCreateIndex() {
    SolrServer server = new HttpSolrServer("http://192.168.10.1:8080/solr");
    SolrInputDocument document = new SolrInputDocument();
    document.addField("id", "c0001"); //唯一约束,schema.xml中默认有一个id的field
    document.addField("product_name", "solr全文检索");//商品名称
    document.addField("product_price", 86.5f);//商品价格
    document.addField("product_picture", "382782828.jpg");//商品图片
    document.addField("product_description", "这是一本关于solr的书籍!");//商品描述
    document.addField("product_catalog_name", "javabook");//商品分类
    UpdateResponse response = server.add(document);
    server.commit(); // 提交
}

2.2 删除索引

//删除索引
@Test
public void testDeleteIndex() {
    SolrServer solrServer = new HttpSolrServer("http://192.168.10.1:8080/solr");
    UpdateResponse response = solrServer.deleteById("c0001");//根据id删除
    solrServer.deleteByQuery("product_keywords:教程");//自动查询条件删除
    solrServer.commit(); // 提交
}

3. 搜索

3.1 搜索索引

// 搜索
@Test
public void testSearch() throws SolrServerException {
    SolrServer solr = new HttpSolrServer("http://192.168.10.1:8080/solr");        
    SolrQuery query = new SolrQuery(); // 查询对象
    //设置查询条件,名称“q”是固定的且必须 的
    //搜索product_keywords域,product_keywords是复制域包括product_name和product_description
    query.set("q", "product_keywords:java教程");
    QueryResponse response = solr.query(query); // 请求查询      
    SolrDocumentList docs = response.getResults();   // 查询结果       
    System.out.println("查询文档总数" + docs.getNumFound()); // 查询文档总数
    for (SolrDocument doc : docs) {
        String id = (String) doc.getFieldValue("id"); //商品主键
        String product_name = (String) doc.getFieldValue("product_name"); //商品名称
        Float product_price = (Float) doc.getFieldValue("product_price"); //商品价格
        String product_picture = (String) doc.getFieldValue("product_picture"); //商品图片
        String product_catalog_name = (String) doc.getFieldValue("product_catalog_name"); //商品分类
        System.out.println("=============================");
        System.out.println(id);
        System.out.println(product_name);
        System.out.println(product_price);
        System.out.println(product_picture);
        System.out.println(product_catalog_name);
    }
}

3.2 组合查询

AND 、 OR 、 NOT 条件:
TO 条件:
[6,9] 相当于 6<=price<=9
(6,9) 相当于 1< price< 9

//根据商品分类、价格范围、关键字查询,查询结果按照价格降序排序
@Test
public void testSearch2() throws SolrServerException {
    SolrServer solr = new HttpSolrServer("http://192.168.10.1:8080/solr");
    SolrQuery query = new SolrQuery(); // 查询对象
    // 搜索product_keywords域,product_keywords是复制域包括product_name和product_description
    // 设置商品分类、关键字查询
    // query.set("q", "product_keywords:挂钩 AND  product_catalog_name:幽默杂货");
    query.setQuery("product_keywords:挂钩 AND product_catalog_name:幽默杂货");
    query.set("fq", "product_price:[1 TO 20]"); // 设置价格范围
    // 查询结果按照价格降序排序
    // query.set("sort", "product_price desc");
    query.addSort("product_price", ORDER.desc);

    QueryResponse response = solr.query(query); // 请求查询        
    SolrDocumentList docs = response.getResults(); // 查询结果        
    System.out.println("查询文档总数" + docs.getNumFound()); // 查询文档总数
    for (SolrDocument doc : docs) {
        String id = (String) doc.getFieldValue("id");  // 商品主键            
        String product_name = (String) doc.getFieldValue("product_name"); // 商品名称
        Float product_price = (Float) doc.getFieldValue("product_price"); // 商品价格
        String product_picture = (String) doc.getFieldValue("product_picture"); // 商品图片
        String product_catalog_name = (String) doc.getFieldValue("product_catalog_name"); // 商品分类
        System.out.println("=============================");
        System.out.println("id=" + id);
        System.out.println("product_name=" + product_name);

        System.out.println("product_price=" + product_price);
        System.out.println("product_picture=" + product_picture);
        System.out.println("product_catalog_name=" + product_catalog_name);
    }
}

3.3 分页高亮

// 分页和高亮
@Test
public void testSearch3() throws SolrServerException {
    SolrServer solr = new HttpSolrServer(urlString);
    SolrQuery query = new SolrQuery();
    query.setQuery("product_keywords:透明挂钩 "); // 设置商品分类、关键字查询
    
    // 分页参数
    int pageSize = 2; // 每页显示记录数
    int curPage = 2; // 当前页码
    int begin = pageSize * (curPage - 1); // 开始记录下标
    query.setStart(begin); // 起始下标
    query.setRows(pageSize); // 结束下标
    
    // 设置高亮参数
    query.setHighlight(true); // 开启高亮组件
    query.addHighlightField("product_name");// 高亮字段
    query.setHighlightSimplePre("<span color='red'>");//        前缀标记
    query.setHighlightSimplePost("</span>");// 后缀标记
    QueryResponse response = solr.query(query); // 请求查询
    SolrDocumentList docs = response.getResults();
    System.out.println("查询文档总数" + docs.getNumFound());
    for (SolrDocument doc : docs) {
        String id = (String) doc.getFieldValue("id");
        String product_name = (String) doc.getFieldValue("product_name");
        Float product_price = (Float) doc.getFieldValue("product_price");
        String product_picture = (String) doc.getFieldValue("product_picture");
        String product_catalog_name = (String) doc.getFieldValue("product_catalog_name");
        
        System.out.println("=============================");
        System.out.println("id=" + id);
        System.out.println("product_name=" + product_name);
        System.out.println("product_price=" + product_price);
        System.out.println("product_picture=" + product_picture);
        System.out.println("product_catalog_name=" + product_catalog_name);
        
        // 高亮信息
        if (response.getHighlighting() != null) {
            if (response.getHighlighting().get(id) != null) {
                Map<String, List<String>> map = response.getHighlighting().get(id);// 取出高亮片段
                if (map.get("product_name") != null) {
                    for (String s : map.get("product_name")) {
                        System.out.println(s);
                    }
                }
            }
        }
    }
}
点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
3年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Wesley13 Wesley13
3年前
FLV文件格式
1.        FLV文件对齐方式FLV文件以大端对齐方式存放多字节整型。如存放数字无符号16位的数字300(0x012C),那么在FLV文件中存放的顺序是:|0x01|0x2C|。如果是无符号32位数字300(0x0000012C),那么在FLV文件中的存放顺序是:|0x00|0x00|0x00|0x01|0x2C。2.  
Stella981 Stella981
3年前
Solr集群架构概述及delta
背景由于项目原因,重新熟悉了下Solr,版本为3.6,搭建了主从Solr服务,并使用DIH从RDBMS数据源增量更新索引。其实也没什么技术含量,就是简单做个总结,分别从部署架构和增量更新两个方面说明下。SolrReplicationsolr的主从其实是他的replication(https://www.oschi
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
Java日期时间API系列30
  实际使用中,经常需要使用不同精确度的Date,比如保留到天2020042300:00:00,保留到小时,保留到分钟,保留到秒等,常见的方法是通过格式化到指定精确度(比如:yyyyMMdd),然后再解析为Date。Java8中可以用更多的方法来实现这个需求,下面使用三种方法:使用Format方法、 使用Of方法和使用With方法,性能对比,使用
Stella981 Stella981
3年前
Solr搜索引擎入门知识汇总
1.技术选型,为什么用solr而不用lucene,或者其他检索工具lucene:需要开发者自己维护索引文件,在多机环境中备份同步索引文件很是麻烦Lucene本质上是搜索库,不是独立的应用程序。而Solr是。Lucene专注于搜索底层的建设,而Solr专注于企业应用。Lucene不负责支撑搜索服务所必须的管理,而Solr负责。一句
Stella981 Stella981
3年前
Linux应急响应(二):捕捉短连接
0x00前言​短连接(shortconnnection)是相对于长连接而言的概念,指的是在数据传送过程中,只在需要发送数据时,才去建立一个连接,数据发送完成后,则断开此连接,即每次连接只完成一项业务的发送。在系统维护中,一般很难去察觉,需要借助网络安全设备或者抓包分析,才能够去发现。0x01应急场景​
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
美凌格栋栋酱 美凌格栋栋酱
5个月前
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(