環境介紹:
阿里雲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
name instanceDir換成剛纔創建的core目錄名稱,其它默認不變(這幾個是什麼意思不用介紹了吧 一眼就看懂了)
創建成功後可以在這裏看到,如果你失敗了不要懷疑什麼肯定是你的插入姿勢不對 google吧
二、導入mysql數據
有時候我們有很大的數據量需要直接導入,那麼就在這裏了,完成上面一步才能繼續操作這裏。
因爲要用到Mysql所以我們要把連接的驅動放到Tomcat下Solr目錄Lib包中(ps:這裏驅動版本和你的Mysql版本你要確保能用哦)
mysql-connector-java-5.1.45.jar我下載好並且已經放進去了
在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.xml中entity 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"/>
這裏的Name和data-config.xml中的Name對應 type自己對應吧 屬性意思自行Google瞭解
這就算完成配置了 然後就是重啓tomcat
更深入的瞭解Google一下都有。然後查詢數據看一下
可以看到7條數據進來了 so easy
三、配置IK分詞查詢
爲什麼要用就不用說了,Solr也有自帶中分分詞但是覺得沒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.dic和stopword.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推薦
實現類似某寶搜索推薦類似的功能
待更新,未完。