Linux環境Tomcat部署Solr+導入Mysql數據+Ik分詞+java使用solrj檢索高亮實現代碼全過程+suggest推薦

環境介紹:

阿里雲CentOS 7.3
Apache Tomcat8.5
(安裝路徑:/usr/local/tomcat8.5)
Apache Solr7.5
(部署路徑:/usr/local/tomcat8.5/webapps/solr)
(下載地址:http://www.apache.org/dyn/closer.lua/lucene/solr/7.5.0)
Apache Mysql 5.7.23


Solr不用過多介紹 用來實現全文檢索功能 網上的Solr教程實在太少了 就出一套從安裝到Java實現代碼的過程吧!自己也踩了很多坑把使用的過程記錄下來也給有需要的人學習一下,以前只是記錄自己實現的過程,過程有很多種更便捷的方式去做,但是我這裏就不寫了,大家跟着這樣下面這樣做是覺得能實現功能的。Win系統登錄Linux終端可以下載Git 或者其它。


一、Linux安裝solr7.5並部署到Tomcat

進入/usr/local目錄

cd /usr/local

下載solr

wget http://mirror.bit.edu.cn/apache/lucene/solr/7.5.0/solr-7.5.0.tgz

解壓Solr文件

tar -zxvf solr-7.5.0.tgz  

重命名爲(solr)

mv -f solr-7.5.0 solr

Tips:
solr/bin/solr start -force 也可以運行
NOTE: Please install lsof as this script needs it to determine if Solr is listening on port 8983.
啓動後可以看到端口是8983
輸入服務器IP:8983可以訪問solr admin頁面(別忘記打開端口不然訪問不到哦)
繼續操作部署到Tomcat中這裏我的tomcat目錄路徑/usr/local/tomcat8.5

首先tomcat建立一個solr文件夾並且進入到該目錄

mkdir /usr/local/tomcat8.5/webapps/solr
cd /usr/local/tomcat8.5/webapps/solr

把solr中webapp拷貝到我們的tomcat拷貝過來

cp -f /usr/local/solr/server/solr-webapp/webapp/* .

創建一個solr core目錄新增的core可以放在這裏(不是非要放在tomcat路徑下,看個人存儲)

mkdir solr-home
cd solr-home

把Solr的數據拷貝過來

cp -r /usr/local/solr/server/solr/* .

創建core名字爲doc_work等一下會用到

mkdir doc_work
cd doc_work
cp -r /usr/local/solr/server/solr/configsets/_default/conf/* .

編輯web.xml解決solr訪問admin ui權限問題

vim ../WEB-INF/web.xml

在第一個filter前添加下面代碼 env-entry-value地址換成上面一步自己創建的路徑 solr-home

<env-entry>
       <env-entry-name>solr/home</env-entry-name>     
        <env-entry-value>/usr/local/tomcat8.5/webapps/solr/solr-home</env-entry-value>
       <env-entry-type>java.lang.String</env-entry-type>
</env-entry>

將這裏代碼註釋掉
註釋掉這段代碼

複製JAR包

cd ../WEB-INF/lib/
cp -r /usr/local/solr/server/lib/ext/ .
cp -r /usr/local/solr/server/lib/metrics*.jar .
cp -r /usr/local/solr/dist/solr-dataimporthandler-extras-7.5.0.jar .
cp -r /usr/local/solr/dist/solr-dataimporthandler-7.5.0.jar .
cp -r /usr/local/solr/dist/solr-clustering-7.5.0.jar .

創建classes目錄把log4j.xml拷貝進去

mkdir ../classes
cd ../classes
cp -r /usr/local/solr/server/resources/log4j2.xml .
cp -r /usr/local/solr/server/lib/ext/* /usr/local/tomcat8.5/lib/

現在就算部署好Solr了我們啓動Tomcat
瀏覽器訪問:http://換成你的IP地址/solr/index.html
admin Ui頁面創建Core

name instanceDir換成剛纔創建的core目錄名稱,其它默認不變(這幾個是什麼意思不用介紹了吧 一眼就看懂了)

創建成功後
創建成功後可以在這裏看到,如果你失敗了不要懷疑什麼肯定是你的插入姿勢不對 google吧

二、導入mysql數據

有時候我們有很大的數據量需要直接導入,那麼就在這裏了,完成上面一步才能繼續操作這裏。
因爲要用到Mysql所以我們要把連接的驅動放到Tomcat下Solr目錄Lib包中(ps:這裏驅動版本和你的Mysql版本你要確保能用哦)
mysql-connector-java-5.1.45.jar我下載好並且已經放進去了
Mysql連接驅動
在doc_work目錄下創建 data-config.xml
創建直接vim data-config.xml 或者 vi data-config.xml命令即可
vim data-config.xml
複製並修改以下內容到vim保存(把下面jdbc連接名戶名密碼換成自己的,還有要查詢的表以及字段,要記住這裏的field name等下還要用到)

<?xml version="1.0" encoding="UTF-8" ?>
<dataConfig>
    <dataSource driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/snow?charactorEncoding=utf-8" user="root" password="123"/>
    <document>
        <entity name="doc_file_info" query="select * from doc_file_info">
            <field column="id" name="id" />
            <field column="tenant_id" name="tenant_id" />
            <field column="doc_info_id" name="doc_info_id" />
            <field column="name" name="name" />
            <field column="path" name="path" />
            <field column="size" name="size" />
            <field column="suffix" name="suffix" />
            <field column="views" name="views" />
            <field column="downtions" name="downtions" />
            <field column="rating_status" name="rating_status" />
            <field column="share_status" name="share_status" />
            <field column="del_flag" name="del_flag" />
        </entity>
    </document>
</dataConfig>

下面把data-config.xml引用添加到solrconfig.xml

vim solrconfig.xml

輸入“/requestHandler” 回車 搜索代碼塊把下面代碼放在一塊方便管理。

<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
       <lst name="defaults">
          <str name="config">data-config.xml</str>
       </lst>
  </requestHandler>

編輯managed-schema把剛纔新增的data-config.xmlentity fileld字段添加到這裏哦

<field name="tenant_id" type="string" indexed="true" stored="true"/>
<field name="doc_info_id" type="string" indexed="true" stored="true"/>
<field name="name" type="string" indexed="true" stored="true"/>
<field name="path" type="string" indexed="true" stored="true"/>
<field name="size" type="string" indexed="true" stored="true"/>
<field name="suffix" type="string" indexed="true" stored="true"/>
<field name="views" type="string" indexed="true" stored="true"/>
<field name="downtions" type="string" indexed="true" stored="true"/>
<field name="rating_status" type="string" indexed="true" stored="true"/>
<field name="share_status" type="string" indexed="true" stored="true"/>
<field name="del_flag" type="string" indexed="true" stored="true"/>

這裏的Namedata-config.xml中的Name對應 type自己對應吧 屬性意思自行Google瞭解
這就算完成配置了 然後就是重啓tomcat

導入Mysql數據步驟
更深入的瞭解Google一下都有。然後查詢數據看一下
查詢數據
可以看到7條數據進來了 so easy

三、配置IK分詞查詢

爲什麼要用就不用說了,Solr也有自帶中分分詞但是覺得沒Ik還用
看一下普通的分詞↓
普通分詞
Ik分詞是這樣的 ↓
Ik分詞
我們需要引用JAR包
下載地址:https://search.maven.org/remotecontent?filepath=com/github/magese/ik-analyzer-solr7/7.x/ik-analyzer-solr7-7.x.jar
還是放在你的Solr部署在tomcat的lib路徑
在我們創建的core(doc_work)目錄下找到managed-schema編輯添加

vim managed-schema

代碼和上面一下輸入/fieldType向下搜索一下放到一塊的位置方便管理

<fieldType name="text_ik" class="solr.TextField">
  <analyzer type="index">
      <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="false" conf="ik.conf"/>
      <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
  <analyzer type="query">
      <tokenizer class="org.wltea.analyzer.lucene.IKTokenizerFactory" useSmart="true" conf="ik.conf"/>
      <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
</fieldType>

添加該代碼保存 哦對了 需要用ik分詞的field type屬性改成text_ik即可

例如:

<field name="name" type="text_ik" indexed="true" stored="true"/>

完成以上步驟重啓Tomcat即可使用
tips:
使用Ik的擴展配置在Solr目錄下創建IKAnalyzer.cfg.xml
內容:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">  <properties>  
    <comment>IK Analyzer 擴展配置</comment>
    <!--用戶可以在這裏配置自己的擴展字典-->
    <entry key="ext_dict">my.dic;</entry> 
    
    <!--用戶可以在這裏配置自己的擴展停止詞字典-->
    <entry key="ext_stopwords">stopword.dic;</entry> 
    </properties>

Tips:
my.dic即爲擴展分詞庫,分詞庫可以爲多個 以分號隔開即可。停止詞庫一樣。
新增my.dicstopword.dic文件。文件格式必需是:無BOM的UTF-8格式

這纔算完成Ik分詞的配置

四、使用solrj上傳檢索pdf word txt等文件

這部分寫的是java中使用solrj並且服務器solr配置
先看solr配置吧。等會貼上來java Demo(spring boot +solrj實現檢索)
doc_work目錄下 編輯添加一下代碼保存
創建 tika-data-config.xml

vim tika-data-config.xml 

添加內容

 <dataConfig>
<script><![CDATA[
        id = 1;
        function GenerateId(row) {
            row.put('id', (id ++).toFixed());
            return row;
        }
        function WipOffHtml(row) {
            var file = row.get('file');
            row.put('file',file.substr(0,file.indexOf('.')));
            return row;
        }
       ]]>
    </script>
    <dataSource type="BinFileDataSource"/>
       <document>
        <entity name="files" dataSource="binary"  rootEntity="false" processor="FileListEntityProcessor"
            baseDir="/tmp" fileName=".*.(doc)|(pdf)|(xls)|(ppt)|(docx)|(txt)|(html)" recursive="true">
        <field column="file" name="fileName"/>
        <field column="fileAbsolutePath" name="filePath"/>
        <field column="fileSize" name="size" />
        <field column="fileLastModified" name="lastModified" />
       <entity  name="documentImport"  processor="TikaEntityProcessor" url="${files.fileAbsolutePath}" format="text" transformer="HTMLStripTransformer,RegexTransformer,script:GenerateId">
         <field column="id" name="id" />
         <field column="Author" name="author" meta="true"/>
         <field column="title" name="title" meta="true"/>
         <field column="text" name="text" stripHTML="true" regex="\t|\r|\n|\s" replaceWith="" />
      </entity>
     </entity>
   </document>
</dataConfig>

把這兩個裏面的包拷貝到我們的solr-home目錄下

cp -r /usr/local/solr/dist/ /usr/local/tomcat8.5/webapps/solr/solr-home
cp -r /usr/local/solr/contrib/ /usr/local/tomcat8.5/webapps/solr/solr-home

編輯solrconfig.xml找到lib dir 這裏幾個修改成我們自己的路徑

vim solrconfig.xml

我這修改成:

  <lib dir="/usr/local/tomcat8.5/webapps/solr/solr-home/contrib/extraction/lib" regex=".*\.jar" />
  <lib dir="/usr/local/tomcat8.5/webapps/solr/solr-home/dist/" regex="solr-cell-\d.*\.jar" />

  <lib dir="/usr/local/tomcat8.5/webapps/solr/solr-home/contrib/clustering/lib/" regex=".*\.jar" />
  <lib dir="/usr/local/tomcat8.5/webapps/solr/solr-home/dist/" regex="solr-clustering-\d.*\.jar" />

  <lib dir="/usr/local/tomcat8.5/webapps/solr/solr-home/contrib/langid/lib/" regex=".*\.jar" />
  <lib dir="/usr/local/tomcat8.5/webapps/solr/solr-home/dist/" regex="solr-langid-\d.*\.jar" />

  <lib dir="/usr/local/tomcat8.5/webapps/solr/solr-home/contrib/velocity/lib" regex=".*\.jar" />
  <lib dir="/usr/local/tomcat8.5/webapps/solr/solr-home/dist/" regex="solr-velocity-\d.*\.jar" />

編輯solrconfig.xml添加tika-data-config.xml引用

vim solrconfig.xml

內容:

 <requestHandler name="/filedataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
      <lst name="defaults">
             <str name="config">tika-data-config.xml</str>
       </lst>
 </requestHandler>

編輯managed-schema增加字段(ps:已有的不用加了)

vim managed-schema

內容:

  <field name="text" type="text_ik" indexed="true" stored="true"/>
  <field name="title" type="text_ik" indexed="true" stored="true"/>
  <field name="Author" type="text_ik"/>
  <field name="fileName" type="text_ik" indexed="true" stored="true"/>
  <field name="Application-Name" type="text_general"/>
  <field name="filePath" type="text_ik" indexed="true" stored="true"/>

完成之後重啓Tomcat

下面是使用solrj完成檢索不解釋了一個Demo寫的很不好主要是打通過程直接上代碼:
添加JAR(至於其他的spring包和其他用的包這裏就不說了)

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

application.yml

spring:
 data:
    solr:
      host: http://你的IP/solr/doc_work

這裏輸入會有提示不要直接複製哈 省的空格什麼錯誤

    @Autowired
    private SolrClient solrClient;

    @RequestMapping(path = "/search")
    public ModelAndView index(HttpServletRequest request) throws IOException, SolrServerException {
        ModelAndView model = new ModelAndView();
        String key = request.getParameter("key");
        SolrQuery query = new SolrQuery();
        query.set("q", "filename:" + key);
        //query.set("q", "fileName:" + key + " " + "text:" + key);
        query.set("fl", "filename,size,filepath,author,text,id");
        query.setHighlight(true);
        query.addHighlightField("text");
        query.addHighlightField("filename");
        //標記,高亮關鍵字前綴
        query.setHighlightSimplePre("<font color='blue'>");
        //後綴
        query.setHighlightSimplePost("</font>");
        QueryResponse response2 = solrClient.query(query);
        SolrDocumentList list2 = response2.getResults();
        Map<String, Map<String, List<String>>> hi = response2.getHighlighting();
        List<FileInfo> fileList = new ArrayList<FileInfo>();
        for (SolrDocument document : list2) {
            Map<String, List<String>> fieldMap = hi.get(document.get("id"));
            List<String> text = fieldMap.get("text");
            List<String> fileName = fieldMap.get("filename");
            List<String> filePath = (List<String>) document.get("filepath");
            String size = (String) document.get("size");
            String author = (String) document.get("author");
            FileInfo file = new FileInfo(null == fileName || fileName.size() == 0 ? (String) document.get("filename") : fileName.get(0), filePath.get(0), author, null == text || text.size() == 0 ? (String) document.get("text") : text.get(0), size);
            file.setSize(ByteUtils.formatByteSize(Long.valueOf(file.getSize())));
            fileList.add(file);
        }
        model.setViewName("index");
        model.addObject("fileList", fileList);
        return model;
    }

    @RequestMapping("/addFileIndex")
    @ResponseBody
    public RespModule addFileIndex(MultipartHttpServletRequest request) {
        RespModule respModule = new RespModule();
        try {
            FileMeta fileMeta = uploadupFile(request, "userfiles/file/");
            ContentStreamUpdateRequest updateRequest = new ContentStreamUpdateRequest("/update/extract");
            updateRequest.addFile(new File(fileMeta.getFileUrl()), fileMeta.getFileType());
            updateRequest.setParam("literal.id", fileMeta.getFileName());
            updateRequest.setParam("literal.filename", fileMeta.getFileName());
            updateRequest.setParam("literal.filepath", fileMeta.getFileUrl());
            updateRequest.setParam("literal.size", fileMeta.getFileSize());
            updateRequest.setParam("text", "attr_content");

            updateRequest.setAction(AbstractUpdateRequest.ACTION.COMMIT, true, true);

            solrClient.request(updateRequest);
            QueryResponse rsp = solrClient.query(new SolrQuery("*:*"));

            SolrDocumentList solrDocumentList = rsp.getResults();

            ListIterator<SolrDocument> listIterator = solrDocumentList
                .listIterator();
            while (listIterator.hasNext()) {
                SolrDocument solrDocument = listIterator.next();
                System.out.println(solrDocument.getFieldValue("filename"));
            }

        } catch (Exception e) {
            respModule.setCode(ServiceErrorCode.ERROR.getErrorCode());
            e.printStackTrace();
        }
        return respModule;
    }


    /**
     * Localhost Upload
     * @return
     */
    public FileMeta uploadupFile(MultipartHttpServletRequest request, String pathStr) {
        // SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
        FileMeta fileMeta = null;
        Iterator<String> itr = request.getFileNames();

        MultipartFile mpf = null;
        String savePath = request.getSession().getServletContext().getRealPath("/") + pathStr + DateUtils.formatDate(new Date(), "yyyyMMdd") + "/";
        //String saveUrl = request.getContextPath() + "/" + pathStr + DateUtils.formatDate(new Date(), "yyyyMMdd") + "/";
        if (itr.hasNext()) {
            mpf = request.getFile(itr.next());
            String originalFilename = mpf.getOriginalFilename();
            fileMeta = new FileMeta();
            fileMeta.setFileName(originalFilename);
            fileMeta.setOldName(originalFilename);
            fileMeta.setFileSize(String.valueOf(mpf.getSize()));
            fileMeta.setFileType(mpf.getContentType());
            try {
                fileMeta.setBytes(mpf.getBytes());
                fileMeta.setFileUrl(savePath + originalFilename);
                FileUtils.createFile(savePath + originalFilename);
                FileCopyUtils.copy(mpf.getBytes(), new FileOutputStream(savePath + originalFilename));
            } catch (IOException e) {
                e.printStackTrace();
                System.out.println(e.getMessage());
            }
        }
        return fileMeta;
    }

上傳的方法是這個addFileIndex
PostMan上傳一下
在這裏插入圖片描述
我們看一下 solr admin 後臺
上傳的數據
這裏沒有test沒有txt裏的內容 初步判斷是文件在我本地 服務器沒讀到 本來是好的這個我後續更新一下

以上代碼看看就知道意思了 所需要的工具類等我就不寫了 主要是個實現的過程思路
下面是搜索的頁面一個簡單的Demo就是這樣(Demo很爛 別噴 如果有需要的話我還是會把源碼上傳到gitee or github分享一下給你們的)
這裏是頁面

以上solr配置稍加變通在服務器可掃描盤admin Ui導入數據和導入mysql數據類似(自行百度)

五、suggest推薦

實現類似某寶搜索推薦類似的功能
推薦

待更新,未完。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章