Solr7.4.0应用部署Demo,比较全面完整,亲测有效

论坛 期权论坛 脚本     
匿名网站用户   2020-12-21 11:19   2701   0

本文参考:
http://www.cnblogs.com/tony-zt/p/9260017.html
http://www.importnew.com/12707.html
https://blog.csdn.net/wzy18210825916/article/details/80946454
https://blog.csdn.net/column/details/17959.html
https://www.2cto.com/database/201708/668379.html
感谢以上分享的作者。
本篇为Solr7.4版本 + windows10系统为案例进行配置和部署。通过本篇内容小白都可以掌握Solr的基本使用方法,get新技能。

系统要求:
JDK 1.8以上
一、“安装”
从官网下载Solr7.4(或本资源包内直接解压,本包内也是官网下载的)

下载地址:https://mirrors.tuna.tsinghua.edu.cn/apache/lucene/solr/7.4.0/

因为我是Windows系统所以选的是.zip的版本,如果是Linux系统需要用.tgz的版本,下面都是以Windows系统下的示例。

Solr7.4是免安装的,解压后就可以直接使用了。

win+R,在打开输入栏:输入 cmd ,点确定,弹出命令提示符窗口
这里写图片描述
在窗口中输入你的Solr安装的盘符加冒号,比如 D:回车

然后再输入:cd 你的Solr安装路径一直到bin文件夹,
比如我的是: D:\Work_Space\Solr\solr-7.4.0\bin
这里写图片描述
回车,然后再输入:solr start
会出现下面的信息,7.4的里面会有一些错误信息,但不影响使用。6.6版本的没有,6.6版本的配置方法和7.4是完全一样的。如果有强迫症的可以使用6.6.0或6.6.1(其他的没试过)
这里写图片描述
Solr的默认端口号是8983
启动成功后,可以用浏览器验证一下:
地址栏输入:http://localhost:8983/solr
就会出现Solr控制台主页面:
这里写图片描述
提前声明一下,Solr7.4是自带Jetty服务器的,不需要集成到Tomcat服务器中。反正我是不会这么做,因为分离开方便后期维护,如果想要修改Solr的配置也不需要停掉项目。所以,为什么要部署到Tomcat?不啰嗦了,自己看吧。

二、创建core
在cmd窗口输入: solr create -c testcore
testcore 是自己起的名字,回车后会出现下面的信息(还是会有log4j2的错误信息,不用管)
这里写图片描述
我们刷新一下控制台可以看到:
这里写图片描述
点击Core Selector,选择刚刚创建的testcore,可以看到如下界面:
这里写图片描述
Core也可以直接在控制台创建,但是需要自己先再Solr安装根目录/server/solr目录下创建一个core文件夹,而且里面要自己创建一个data文件夹。然后通过控制台的Core Admin创建core 。
个人建议直接在cmd窗口用命令创建,省力省心还可靠。
网上还有自己拷贝conf文件夹到自己创建core 等等的操作,感觉太麻烦。有兴趣的自行百度。

三、配置core索引MySQL数据

1、把数据库驱动jar包放到
Solr安装根目录/server/solr-webapp/webapp/WEB-INF/lib下
这里写图片描述
2、把Solr安装根目录/dist文件夹下的
solr-dataimporthandler-x.x.x.jar
solr-dataimporthandler-extras-x.x.x.jar
这里写图片描述
放到Solr安装根目录/server/solr-webapp/webapp/WEB-INF/lib下
这里写图片描述
3、Solr安装根目录/server/solr/核心/conf路径下添加文件data-config.xml,并添加以下内容(示范如下)

3.1全量索引

<dataConfig>
    <!-- url如果包含特殊字符如";",必须使用html转移字符 -->
    <dataSource driver="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/solrdb"     user="root" password="123456"/>
    <document>
        <!-- query为全量更新SQL -->
        <entity name="testdb" pk="tid" query="select * from testdb">
<!-- 每一个field映射着数据库中列与文档中的域,column是数据库列,name是solr的域(必须是在managed-schema文件中配置过的域才行) -->
            <field column="tid" name="idid"/>
            <field column="tname" name="TName"/>
            <field column="tbirthday" name="TBirthDay"/>

        </entity>
    </document>
</dataConfig>

3.2增量索引(含同时具有全量和增量索引的功能)
可以直接配置这一个跳过3.1,上面3.1的配置是为了能让你区别全量和增量配置的不同之处。

3.2.1
solr默认使用UTC时间,即与中国时差8小时,所以需要修改配置文件:
Solr安装根目录/bin/solr.in.sh

SOLR_TIMEZONE=”UTC+8”
默认是注释掉的,找到SOLR_TIMEZONE修改后面的值为UTC+8
注意:如果单纯修改solr.in.sh文件没有作用,就修改和solr.in.sh同目录下的solr.cmd文件,修改其中的set SOLR_TIMEZONE=UTC为set SOLR_TIMEZONE=UTC+8

3.2.2
修改mysql数据库的表结构,添加一个时间戳字段,当某行数据发生更新时该字段自动更新为修改数据的时间,为solr增量添加提供服务(范例如下)
ALTER TABLE testdb ADD last_modified TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP DEFAULT current_timestamp

3.2.3
修改solr/server/solr/核心/conf路径下添加文件data-config.xml,并添加增量SQL(示范如下)

就是多添加了deltaQuery部分

<dataConfig>
    <!-- url如果包含特殊字符如";",必须使用html转移字符 -->
    <dataSource driver="com.mysql.jdbc.Driver" url="jdbc:mysql://127.0.0.1:3306/solrdb" user="root" password="123456"/>
    <document>
        <!-- query为全量更新SQL -->
        <entity name="testdb" pk="tid" query="select * from testdb"
            deltaQuery="select tid from testdb where last_modified > '${dih.last_index_time}'">
            <!-- 每一个field映射着数据库中列与文档中的域,column是数据库列,name是solr的域(必须是在managed-schema文件中配置过的域才行) -->
            <field column="tid" name="idid"/>
            <field column="tname" name="TName"/>
            <field column="tbirthday" name="TBirthDay"/>

        </entity>
    </document>
</dataConfig>

4、修改solrconfig.xml,添加以下内容


data-config.xml

5、修改managed-schema,添加mysql中需要存入solr的字段(示范如下)


准备测试效果:
数据库里的数据:
这里写图片描述
注意:当last_modified的值是0000-00-00 00:00:00时会有错误,
因为java的时间是从1970年开始的,所以不能翻译这个时间,导致的结果就是查不到数据。
现在测试全量更新:依次选择1234
这里写图片描述
结果是:
这里写图片描述
这里写图片描述
测试增量更新,在数据库新添一条数据
注意:增量更新就是只更新有变化的数据,不会更新没有变化的数据。如果增量更新选择clean会删除所有的原索引数据,然后只更新有修改过的数据。
正常使用情况下增量更新的clean是不选择的。这里为了测试更新方式是增量更新的方式,所以选择了clean。切忌用在项目中!!!除非你知道会有什么后果
这里写图片描述
结果是:
这里写图片描述
这里写图片描述
我们看到,之前的两条数据被删除了,只有一条新添加的数据。证明增量更新的功能有效。
四、接下来我们配置一个实用的功能:定时更新
因为数据库的数据可能是动态变化的,为了能和数据库的数据“及时”同步,所以就有了这个功能。
它可以按设定时间自动更新一次索引

4.1修改testcore目录下的配置文件core.properties
name=testcore
config=solrconfig.xml
schema=data-config.xml
dataDir=data

4.2添加实时更新索引相关的jar包:dataimportscheduler-1.2.jar 到
Solr安装根目录/server/solr-webapp/webapp/WEB-INF/lib下

还有两个jar包因为之前已经添加过了就不需要添加了,是
solr-dataimporthandler-x.x.x.jar
solr-dataimporthandler-extras-x.x.x.jar

4.3 修改Solr安装根目录/server/solr-webapp/webapp/WEB-INF/web.xml
把这个添加到里面


org.apache.solr.handler.dataimport.scheduler.ApplicationListener


注意:中间的内容两边不要有空格,容易出现不正常现象

4.4添加更新配置文件:Solr安装根目录/server/solr下新建conf文件夹
在文件夹下新建dataimport.properties文件

#################################################
#                                               #
#       dataimport scheduler properties         #
#                                               #
#################################################

#  to sync or not to sync
#  1 - active; anything else - inactive
syncEnabled=1
#  which cores to schedule
#  in a multi-core environment you can decide which cores you want syncronized
#  leave empty or comment it out if using single-core deployment
#syncCores=game,resource
syncCores=testcore
#  solr server name or IP address
#  [defaults to localhost if empty]
server=localhost
#  solr server port
#  [defaults to 80 if empty]
port=8983
interval=2
#  application name/context
#  [defaults to current ServletContextListener's context (app) name]
webapp=solr
#  URL params [mandatory]
#  remainder of URL
params=/dataimport?command=delta-import&clean=false&commit=true
#  schedule interval
#  number of minutes between two runs
#  [defaults to 30 if empty]

#  重做索引的时间间隔,单位分钟,默认7200,即5天; 
#  为空,为0,或者注释掉:表示永不重做索引
reBuildIndexInterval=7200

#  重做索引的参数
reBuildIndexParams=/dataimport?command=full-import&clean=true&commit=true

#  重做索引时间间隔的计时开始时间,第一次真正执行的时间=reBuildIndexBeginTime+reBuildIndexInterval*60*1000;
#  两种格式:2012-04-11 03:10:00 或者  03:10:00,后一种会自动补全日期部分为服务启动时的日期
reBuildIndexBeginTime=03:10:00

测试定时更新
这里写图片描述
我们先全量更新一下所有数据,然后在数据库添加一条数据,再等一分钟直接查询
更新前
这里写图片描述
更新后
这里写图片描述
五、配置中文分词
solr自带的几个分词器对中文支持并不好,所以需要使用第三方分词器对中文进行分词索引。
常用的分词器有:ansj和ik,前者的效果更好。
注:目前发现ansj分词器索引内容大小超过65248字节时,会报异常,目前尚未找到解决办法
5.1需要的jar包:
ansj_lucene5_plug-5.1.1.2.jar
ansj_seg-5.1.1.jar
ik-analyzer-solr5-5.x.jar
nlp-lang-1.7.2.jar

放到Solr安装根目录/server/solr-webapp/webapp/WEB-INF/lib 中

5.2配置放到Solr安装根目录/server/solr/testcore/conf下的managed-schema
(还是之前配置的那个)

<!-- ik分词器 -->
<fieldType name="text_ik" class="solr.TextField">
   <analyzer type="index">
         <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" />
   </analyzer>
   <analyzer type="query">
         <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="true" />
         <!-- 如果不做同义词,可以不配置下面这个Filter -->
        <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
   </analyzer></fieldType>
<!-- ansj分词器 -->
<fieldType name="text_ansj" class="solr.TextField" positionIncrementGap="100">
  <analyzer type="index">
         <tokenizer class="org.ansj.lucene.util.AnsjTokenizerFactory"  isQuery="false" stopwords="/path/to/stopwords.dic"/>
  </analyzer>
  <analyzer type="query">
        <tokenizer class="org.ansj.lucene.util.AnsjTokenizerFactory" stopwords="/path/to/stopwords.dic"/>
  </analyzer>
</fieldType>

然后为要索引的字段添加分词器,例如

<field name="TName" type="text_ansj" indexed="true" stored="true"/>

测试
这里写图片描述
这里写图片描述

成功了!

SolrJ 操作索引的增、删、查

import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrInputDocument;

import java.io.IOException;
import java.util.Iterator;

public class IndexOperation {
    private static final String urlString = "http://localhost:8983/solr/testcore";
    private static SolrClient solr = new HttpSolrClient.Builder(urlString).build();

    public void addIndexTest(){//添加一个索引

        SolrInputDocument doc = new SolrInputDocument();
        //默认id为主键,当id存在时更新数据,否则添加数据
        doc.addField("id", "3");
        doc.addField("name", "hello world test");
        doc.addField("age", "230");
        doc.addField("addr", "1111");
        try {
            solr.add(doc);
            solr.commit();
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    public void deleteIndexTest(String did){
        //通过id删除索引
        try {
            solr.deleteById(did);
            solr.commit();
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //通过搜索条件删除索引
        //solr.deleteByQuery(query);

    }

    public void selectIndexTest(){// 查询
        SolrQuery query = new SolrQuery();
        // *标示多个任意字符,?标示单个任意字符,~模糊搜索
        query.setQuery("*:*");    //全搜索
        // 分页
        query.setStart(0);
        query.setRows(10);

        QueryResponse queryResponse = null;
        try {
            queryResponse = solr.query(query);
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        SolrDocumentList docs = queryResponse.getResults();
        Iterator<SolrDocument> iter = docs.iterator();
        while(iter.hasNext()){
            SolrDocument doc = iter.next();
            System.out.println(doc.toString());
        }
        try {
            solr.commit();
        } catch (SolrServerException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //测试
    public static void main(String[] args){
        IndexOperation ion=new IndexOperation();
        ion.addIndexTest();
        ion.selectIndexTest();
        System.out.println("---------------分割线-----------------");
        ion.deleteIndexTest("3");
        ion.selectIndexTest();
    }
}

运行结果:
这里写图片描述

七、通过SolrJ对MySQL数据库进行全量更新、增量更新

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;

public class LinkMysql {//对数据库进行的操作,全量更新,增量更新

    private CloseableHttpClient httpclient = null;
    private CookieStore cookieStore = null;
    private final String baseSolrUrl;

    /**
     * 全量导入
     */
    private static final String FULL_IMPORT = "full-import";
    /**
     * 增量导入
     */
    private static final String DELTA_IMPORT = "delta-import";

    public LinkMysql(String baseSolrUrl) {
        if(!baseSolrUrl.endsWith("/")){
            baseSolrUrl += "/";
        }
        this.baseSolrUrl = baseSolrUrl;
    }

    private synchronized void init(){
        if(httpclient == null){
            cookieStore = new BasicCookieStore();
            httpclient = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build();
        }
    }

    public void fullImport(String coreName) throws IOException {
        init();

        HttpPost post = getDataImportPost(coreName, FULL_IMPORT);
        httpclient.execute(post);
    }

    public void deltaImport(String coreName) throws IOException {
        init();

        HttpPost post = getDataImportPost(coreName, DELTA_IMPORT);
        httpclient.execute(post);
    }

    private HttpPost getDataImportPost(String coreName,String command) throws UnsupportedEncodingException{
        HttpPost post = new HttpPost(baseSolrUrl + coreName + "/dataimport?indent=on&wt=json&_=" + new Date().getTime());
        List<NameValuePair> params = new ArrayList<NameValuePair>();
        params.add(new BasicNameValuePair("command", command));
        params.add(new BasicNameValuePair("verbose", "false"));
        if(command.equals(FULL_IMPORT)){
            params.add(new BasicNameValuePair("clean", "true"));
        }
        params.add(new BasicNameValuePair("commit", "true"));
        params.add(new BasicNameValuePair("optimize", "false"));
        params.add(new BasicNameValuePair("core", coreName));
        params.add(new BasicNameValuePair("name", "dataimport"));
        post.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
        return post;
    }

    public void close() throws IOException{
        httpclient.close();
        httpclient = null;
        cookieStore = null;
    }

    public  static void main(String[] args){
        //测试
        LinkMysql dataClient=new LinkMysql("http://localhost:8983/solr/");

        /*全量更新*/
        try {
            dataClient.fullImport("testcore");
            dataClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        /*增量更新*/
       /* try {
            dataClient.deltaImport("testcore");
            dataClient.close();
        } catch (IOException e) {
            e.printStackTrace();
        }*/

    }
}

八、索引高亮显示
需要有一个实体类

public class TXDocument {
    private String id;
    private String path;
    private String content;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPath() {
        return path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }


    public String toString() {
        return "TXDocument{" +
                "id='" + id + '\'' +
                ", path='" + path + '\'' +
                ", content='" + content + '\'' +
                '}';
    }
}

下面来高亮的代码

import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;

import java.io.IOException;
import java.util.List;
import java.util.Map;

public class GaoLiang {

    public void  setHighL(){
        HttpSolrClient solrClient  = new HttpSolrClient.Builder("http://127.0.0.1:8983/solr/testcore").build();

        SolrQuery query = new SolrQuery();

        query.set("q","TName:*回归*");//查询的内容


        //1.过滤器
        //query.set("fq","pprice:[1 TO 100]");//query.setFilterQueries("pprice:[1 TO 100]");也可以用addFiterQuries设置多过滤条件

        //2.排序
        //query.set("sort","pprice desc,id asc");//query.setSort("pprice",ORDER.desc);  addSort


        //3.设置查询到的文档返回的域对象
        //query.set("fl","TBPackageName,PackageTypeID");//query.setFields("id,pname");

        //4.设置默认查询的域
        //query.set("df","pname");

        //5.分页
        //query.set("start",0);  //query.setStart(0)
        //query.set("rows",5);   //query.setRows(5)

        //6.高亮
        //query.set("hl",true);
        //设置高亮域(设置的域必须在查询条件中存在)
        // query.set("h1.fl","TBPackageName");
        //前缀
        // query.set("hl.simple.pre","<em style='color:red'>");
        //后缀
        //query.set("hl.simple.post","</em>");

        query.setHighlight(true);
        query.addHighlightField("TName");
        query.setHighlightSimplePre("<em style='color:red'>");
        query.setHighlightSimplePost("</em>");


        QueryResponse response=null;

        {
            try {
                response = solrClient.query(query);
            } catch (SolrServerException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        SolrDocumentList results = response.getResults();
        System.out.println(results);
        //k是id,内部的map的key是域名,其value是高亮的值集合
        Map<String, Map<String, List<String>>> highlighting = response.getHighlighting();
        System.out.println("匹配的结果总数是-------"+results.getNumFound());
        for(SolrDocument document:results) {
            System.out.println("id----" + document.get("id"));
            System.out.println("pname-----" + document.get("TName"));
            //System.out.println("pprice------" + document.get("pprice"));
            List<String> list = null;
            if(highlighting.get(document.get("id")) != null) {
                list = highlighting.get(document.get("id")).get("TName");
            }else {
                System.out.println("无法获取高亮map");
            }
            System.out.println(list);
            if (list != null && list.size() > 0) {
                System.out.println("高亮显示的内容:----"+list.get(0));
            }else {
                System.out.println("高亮显示的内容为空!!!");
            }
            System.out.println("=========================");
        }
    }

    public static  void main(String[] args){
        GaoLiang gl=new GaoLiang();
        gl.setHighL();
    }

}

运行后的结果:
这里写图片描述
如果之前你对高亮怎么用在前台显示的文字里,看到这个结果你应该能够猜到了,就是给需要高亮的字段加上了html标签,至于加什么效果,用什么标签就自己决定吧。高亮的意思不是闪闪发亮,只是一个让查询字段特别显示的代名词。
把这个以字符串的形式传给前台……后面就不需要我啰嗦了吧。

九、SolrJ读取富文本创建索引
就是读取word、pdf、xml……等文件的内容创建索引

import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.request.AbstractUpdateRequest;
import org.apache.solr.client.solrj.request.ContentStreamUpdateRequest;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FuWenBen {
    public static void main(String[] args)
    {   //测试
        beStart("solr-word.pdf");
    }

    public static void beStart(String fname){
        //富文本存放路径,这是示例就写的简单粗暴一些
        String fileUrl = "E:/WorkSpace/ImportData/"+fname;

        try
        {
            indexFilesSolrCell(fname, fname,fileUrl);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        catch (SolrServerException e)
        {
            e.printStackTrace();
        }
    }
    /**
     * @Author:sks
     * @Description:获取系统当天日期yyyy-mm-dd
     * @Date:
     */
    private static String GetCurrentDate(){
        Date dt = new Date();
        //最后的aa表示“上午”或“下午”    HH表示24小时制    如果换成hh表示12小时制
//        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss aa");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String day =sdf.format(dt);
        return day;
    }

    public static void indexFilesSolrCell(String fileName, String solrId, String path)
            throws IOException, SolrServerException
    {
        String urlString = "http://localhost:8983/solr/testcore";
        SolrClient solr = new HttpSolrClient.Builder(urlString).build();

        ContentStreamUpdateRequest up = new ContentStreamUpdateRequest("/update/extract");
        String contentType = getFileContentType(fileName);
        up.addFile(new File(path), contentType);
        String fileType = fileName.substring(fileName.lastIndexOf(".")+1);
        up.setParam("literal.id", fileName);

        up.setParam("literal.path", path);//文件路径
        up.setParam("literal.pathuploaddate", GetCurrentDate());//文件上传时间
        up.setParam("literal.pathftype", fileType);//文件类型,doc,pdf
        up.setParam("fmap.content", "attr_content");//文件内容
        up.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true);
        solr.request(up);
    }

    /**
     * @Author:sks
     * @Description:根据文件名获取文件的ContentType类型
     * @Date:
     */
    public static String getFileContentType(String filename) {
        String contentType = "";
        String prefix = filename.substring(filename.lastIndexOf(".") + 1);
        if (prefix.equals("xlsx")) {
            contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
        } else if (prefix.equals("pdf")) {
            contentType = "application/pdf";
        } else if (prefix.equals("doc")) {
            contentType = "application/msword";
        } else if (prefix.equals("txt")) {
            contentType = "text/plain";
        } else if (prefix.equals("xls")) {
            contentType = "application/vnd.ms-excel";
        } else if (prefix.equals("docx")) {
            contentType = "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
        } else if (prefix.equals("ppt")) {
            contentType = "application/vnd.ms-powerpoint";
        } else if (prefix.equals("pptx")) {
            contentType = "application/vnd.openxmlformats-officedocument.presentationml.presentation";
        }

        else {
            contentType = "othertype";
        }

        return contentType;
    }
}

测试结果:内容太长,就截取了一部分,证明代码是成功的。
这里写图片描述

十、总结与说明
本文内容都已经测试通过,如有效果与文中不一致,可以解压solr样本对比配置内容。
注意:
为了验证时区调整,demo中修改了solr.cmd(set SOLR_TIMEZONE=UTC+8)
但这会让增量更新出现一个错误,就是更新数据后原数据不能被删除。没找到更好的解决办法。
如果其他地方不需要用这个时间,就不用设置solr.cmd了。
这样dataconfig.properties中的时间和我们的时间差8个小时,但是不影响使用。
暂时先不再深入了。毕竟我连个软件开发工作都找不到,还瞎操什么心。不说了,搬砖去了。

Demo和jar包下载可以到uponhead.com去下,搜索solr就能找到了。是免费的。
如果觉得内容可以的话打赏点小费呗,让楼主吃饭的时候能多加一袋咸菜,搬砖真的很累的。
这里写图片描述
这里写图片描述
本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦:

  • Markdown和扩展Markdown简洁的语法
  • 代码块高亮
  • 图片链接和图片上传
  • LaTex数学公式
  • UML序列图和流程图
  • 离线写博客
  • 导入导出Markdown文件
  • 丰富的快捷键

快捷键

  • 加粗 Ctrl + B
  • 斜体 Ctrl + I
  • 引用 Ctrl + Q
  • 插入链接 Ctrl + L
  • 插入代码 Ctrl + K
  • 插入图片 Ctrl + G
  • 提升标题 Ctrl + H
  • 有序列表 Ctrl + O
  • 无序列表 Ctrl + U
  • 横线 Ctrl + R
  • 撤销 Ctrl + Z
  • 重做 Ctrl + Y

Markdown及扩展

Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档,然后转换成格式丰富的HTML页面。 —— [ 维基百科 ]

使用简单的符号标识不同的标题,将某些文字标记为粗体或者斜体,创建一个链接等,详细语法参考帮助?。

本编辑器支持 Markdown Extra ,  扩展了很多好用的功能。具体请参考Github.

表格

Markdown Extra 表格语法:

项目 价格
Computer $1600
Phone $12
Pipe $1

可以使用冒号来定义对齐方式:

项目 价格 数量
Computer 1600 元 5
Phone 12 元 12
Pipe 1 元 234

定义列表

Markdown Extra 定义列表语法:
项目1
项目2
定义 A
定义 B
项目3
定义 C

定义 D

定义D内容

代码块

代码块语法遵循标准markdown代码,例如:

@requires_authorization
def somefunc(param1='', param2=0):
    '''A docstring'''
    if param1 > param2: # interesting
        print 'Greater'
    return (param2 - param1 + 1) or None
class SomeClass:
    pass
>>> message = '''interpreter
... prompt'''

脚注

生成一个脚注1.

目录

[TOC]来生成目录:

数学公式

使用MathJax渲染LaTex 数学公式,详见math.stackexchange.com.

  • 行内公式,数学公式为:Γ(n)=(n1)!nN
  • 块级公式:

x=b±b24ac2a

更多LaTex语法请参考 这儿.

UML 图:

可以渲染序列图:

Created with Raphal 2.1.2张三张三李四李四嘿,小四儿, 写博客了没?李四愣了一下,说:忙得吐血,哪有时间写。

或者流程图:

Created with Raphal 2.1.2开始我的操作确认?结束yesno
  • 关于 序列图 语法,参考 这儿,
  • 关于 流程图 语法,参考 这儿.

离线写博客

即使用户在没有网络的情况下,也可以通过本编辑器离线写博客(直接在曾经使用过的浏览器中输入write.blog.csdn.net/mdeditor即可。Markdown编辑器使用浏览器离线存储将内容保存在本地。

用户写博客的过程中,内容实时保存在浏览器缓存中,在用户关闭浏览器或者其它异常情况下,内容不会丢失。用户再次打开浏览器时,会显示上次用户正在编辑的没有发表的内容。

博客发表后,本地缓存将被删除。 

用户可以选择 把正在写的博客保存到服务器草稿箱,即使换浏览器或者清除缓存,内容也不会丢失。

注意:虽然浏览器存储大部分时候都比较可靠,但为了您的数据安全,在联网后,请务必及时发表或者保存到服务器草稿箱

浏览器兼容

  1. 目前,本编辑器对Chrome浏览器支持最为完整。建议大家使用较新版本的Chrome。
  2. IE9以下不支持
  3. IE9,10,11存在以下问题
    1. 不支持离线功能
    2. IE9不支持文件导入导出
    3. IE10不支持拖拽文件导入


  1. 这里是 脚注内容.
分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1136255
帖子:227251
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP