搜索学习--Solr全文搜索服务器的基本使用(一)——SolrJ的使用

作为一般的Lucene使用者,我们直接用Lucene虽然可以实现很多自己想要的自定义功能,但是对于一般的项目,为了方便开发和维护,我们通常会使用现成的搜索服务器。现在常用的有SolrElasticSearch
对于Solr服务器如何搭建,Solr服务器的搭建,之前已经整理过,这次,我将使用SolrJ来调用Solr服务器。

在Solr中配置Core

在managed-schema中,主要的配置为:

<uniqueKey>blogId</uniqueKey>
<field name="blogId" type="string" indexed="true" stored="true" required="true" multiValued="false" /> 
<field name="blogTitle" type="text_ik" indexed="true" stored="true" required="true" multiValued="false" /> 
<field name="blogContent" type="text_ik" indexed="true" stored="true" required="true" multiValued="false" /> 
<field name="createTime" type="date" indexed="false" stored="true" required="true" multiValued="false" /> 
<field name="keywords" type="text_ik" indexed="true" stored="false"  multiValued="true"/> 
<copyField source="blogTitle" dest="keywords"/>
<copyField source="blogContent" dest="keywords"/>
<fieldType name="text_ik" class="solr.TextField">
<analyzer type="index" useSmart="false"
                class="org.wltea.analyzer.lucene.IKAnalyzer" />
<analyzer type="query" useSmart="true"
                class="org.wltea.analyzer.lucene.IKAnalyzer" />
</fieldType>

依赖

<dependency>
    <groupId>org.apache.solr</groupId>
    <artifactId>solr-solrj</artifactId>
    <version>6.5.1</version>
</dependency>

SolrServer.Java

package top.yuyufeng.learn.lucene.solr;

import org.apache.solr.client.solrj.impl.HttpSolrClient;

/**
 * @author yuyufeng
 * @date 2017/12/6
 */
public class SolrServer {
    private static HttpSolrClient server = null;
    private final static String solrServerUrl = "http://127.0.0.1:8983/solr/blog";

    public static HttpSolrClient getServer() {
        if (server == null) {
            server = new HttpSolrClient(solrServerUrl);
            server.setDefaultMaxConnectionsPerHost(1000);
            server.setMaxTotalConnections(10000);//最大连接数
            server.setConnectionTimeout(60000);//设置连接超时时间(单位毫秒) 1000
            server.setSoTimeout(60000);//// 设置读数据超时时间(单位毫秒) 1000
            server.setFollowRedirects(false);//遵循从定向
            server.setAllowCompression(true);//允许压缩
        }
        return server;
    }

    public static void main(String[] args) {
        HttpSolrClient client = getServer();
        System.out.println(client);
    }
}

BlogCore.java

package top.yuyufeng.learn.lucene.solr.core;

import org.apache.solr.client.solrj.beans.Field;

import java.util.Date;

/**
 * @author yuyufeng
 * @date 2017/12/6
 */
public class BlogCore {
    @Field
    private String blogId;
    @Field
    private String blogTitle;
    @Field
    private String blogContent;
    @Field
    private Date createTime;
    @Field
    private String keywords;

    public String getBlogId() {
        return blogId;
    }

    public void setBlogId(String blogId) {
        this.blogId = blogId;
    }

    public String getBlogTitle() {
        return blogTitle;
    }

    public void setBlogTitle(String blogTitle) {
        this.blogTitle = blogTitle;
    }

    public String getBlogContent() {
        return blogContent;
    }

    public void setBlogContent(String blogContent) {
        this.blogContent = blogContent;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public String getKeywords() {
        return keywords;
    }

    public void setKeywords(String keywords) {
        this.keywords = keywords;
    }

    @Override
    public String toString() {
        return "BlogCore{" +
                "blogId='" + blogId + '\'' +
                ", blogTitle='" + blogTitle + '\'' +
                ", blogContent='" + blogContent + '\'' +
                ", createTime=" + createTime +
                ", keywords='" + keywords + '\'' +
                '}';
    }
}

BlogSolrDao.java

package top.yuyufeng.learn.lucene.solr.dao;

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.client.solrj.response.UpdateResponse;
import top.yuyufeng.learn.lucene.solr.SolrServer;
import top.yuyufeng.learn.lucene.solr.core.BlogCore;

import java.awt.print.Pageable;
import java.util.List;
import java.util.Map;

/**
 * @author yuyufeng
 * @date 2017/12/6
 */
public class BlogSolrDao{
    HttpSolrClient server;

    public BlogSolrDao() {
        server = SolrServer.getServer();
    }

    /**
     * 按Bean  添加/修改 索引
     *
     * @throws Exception
     */
    public int addIndex(BlogCore entity) throws Exception {
        server.addBean(entity);
        UpdateResponse updateResponse = server.commit();
        return updateResponse.getStatus();
    }


    /**
     * 按Bean  添加/修改 索引
     *
     * @throws Exception
     */
    public int addIndexList(List<BlogCore> entitys) throws Exception {
        server.addBeans(entitys);
        UpdateResponse updateResponse = server.commit();
        return updateResponse.getStatus();

    }

    /**
     * 删除索引 按查询
     *
     * @throws Exception
     */
    public int deleteAll() throws Exception {
        String query = "*:*";
        server.deleteByQuery(query);
        server.commit();
        UpdateResponse updateResponse = server.commit();
        return updateResponse.getStatus();
    }

    /**
     * 删除索引 按id
     *
     * @throws Exception
     */
    public int deleteByQuery(Long id) throws Exception {
        server.deleteById(id + "");
        server.commit();
        UpdateResponse updateResponse = server.commit();
        return updateResponse.getStatus();
    }

    //查询所有
    public List<BlogCore> query() throws Exception {
        SolrQuery query = new SolrQuery();
        query.setQuery("*:*");
        query.setStart(0);//开始记录数
        query.setRows(10000);//总条数
        QueryResponse queryResponse = server.query(query);
        List<BlogCore> results = queryResponse.getBeans(BlogCore.class);
        return results;
    }


    //搜索keywords
    public  List<BlogCore> queryByKeyWords(String keywords) throws Exception {

        SolrQuery query = new SolrQuery();
        query.set("q", "keywords:" + keywords);//*通配多个字符
//        query.set("sort", "product_price desc");
        //======高亮设置===
        //开启高亮
        query.setHighlight(true);
        //高亮域
        query.addHighlightField("blogContent");
        query.addHighlightField("blogTitle");
        //前缀
        query.setHighlightSimplePre("<B>");
        //后缀
        query.setHighlightSimplePost("</B>");
        //query.setHighlightSnippets(1);//结果分片数,默认为1
        //query.setHighlightFragsize(1000);//每个分片的最大长度,默认为100

        query.setStart(0);//开始记录数
        query.setRows(100);//总条数
        QueryResponse queryResponse = server.query(query);
        long sum = queryResponse.getResults().getNumFound();
        List<BlogCore> results = queryResponse.getBeans(BlogCore.class);
        //输出高亮
        Map<String, Map<String, List<String>>> highlighting = queryResponse.getHighlighting();

        for (BlogCore result : results) {
            Map<String, List<String>> map = highlighting.get(result.getBlogId()+"");
            List<String> list = map.get("blogTitle");
            if (list != null && list.size() > 0) {
                result.setBlogTitle(list.get(0));
            }
            list = map.get("blogContent");
            if (list != null && list.size() > 0) {
                result.setBlogContent(list.get(0));
            }
        }
       return results;
    }
}

SolrTest.java

package top.yuyufeng.learn.lucene.solr;

import org.junit.Test;
import top.yuyufeng.learn.lucene.solr.core.BlogCore;
import top.yuyufeng.learn.lucene.solr.dao.BlogSolrDao;

import java.util.Date;
import java.util.List;

/**
 * @author yuyufeng
 * @date 2017/12/6
 */
public class SolrTest {

    @Test
    public void testIndex() throws Exception {
        BlogSolrDao blogSolrDao = new BlogSolrDao();
        BlogCore blog = new BlogCore();
        blog.setBlogId("2");
        blog.setBlogTitle("达摩院超越业界龙头");
        blog.setBlogContent("达摩院一定也必须要超越英特尔,必须超越微软,必须超越IBM,因为我们生于二十一世纪,我们是有机会后发优势的。");
        blog.setCreateTime(new Date());
        blogSolrDao.addIndex(blog);
    }

    @Test
    public void testFindAll() throws Exception {
        BlogSolrDao blogSolrDao = new BlogSolrDao();
        List<BlogCore> list = blogSolrDao.query();
        for (BlogCore blogCore : list) {
            System.out.println(blogCore);
        }
    }


    @Test
    public void testSearch() throws Exception {
        BlogSolrDao blogSolrDao = new BlogSolrDao();
        List<BlogCore> list = blogSolrDao.queryByKeyWords("达摩院");
        for (BlogCore blogCore : list) {
            System.out.println(blogCore);
        }
    }
}

运行结果:

启动Solr服务器后,我建立了一些索引,然后我执行Search方法

BlogCore{blogId='2', blogTitle='<B>达摩</B><B>院</B>超越业界龙头', blogContent='<B>达摩</B><B>院</B>一定也必须要超越英特尔,必须超越微软,必须超越IBM,因为我们生于二十一世纪,我们是有机会后发优势的。', createTime=Wed Dec 06 13:38:12 CST 2017, keywords='null'}
BlogCore{blogId='1', blogTitle='马云表达愿景', blogContent='10月11日杭州云栖大会上,马云表达了对新建成的阿里巴巴全球研究<B>院</B>—阿里巴巴<B>达摩</B><B>院</B>的愿景,希望<B>达摩</B><B>院</B>二十年内成为世界第一大经济体,服务世界二十亿人,创造一亿个工作岗位。', createTime=Wed Dec 06 12:03:56 CST 2017, keywords='null'}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容

  • 多少年前的今天 你结束了阳光的缠绵 黑夜越走越长 人间的温暖也悄悄变淡 是谁埋没了花草的绚烂 把一颗颗星辰淹没在尘...
    垄上行云阅读 148评论 6 2
  • 以前听别人说自然疗法的时候,我觉得特别特别神奇,以为就跟中医一样,是单独的一套研究理论,后来才知道这自然疗法包含太...
    心作阅读 506评论 0 0
  • 日精进:"来日方长并不长"我们经常的口头禅就是"等我有空了就如何如何…回头想想自己做了几件承诺过给家人的事? 精进...
    胡玉梅阅读 141评论 0 0
  • 一、大盘、板块 419魔咒迟到了一天,三大指数齐齐下挫,盘面除了芯片一枝独秀几乎没法看。超级品牌表现还算是比较抗跌...
    跟着鹏叔游世界阅读 308评论 0 1