最近接觸搜尋相關的內容,所以熟悉下solr的使用以及如何在java中使用solr實現搜尋功能。
1、solr簡介
Solr是一個獨立的企業級搜尋應用伺服器,它對外提供類似於Web-service的API介面。使用者可以通過http請求,向搜尋引擎伺服器提交一定格式的XML檔案,生成索引;也可以通過Http Get操作提出查詢請求,並得到XML格式的返回結果。
2、倒排索引
有的人會疑惑,搜尋通過資料庫也能直接查到為什麼還要solr這類搜尋引擎。例如我現在要搜尋"solr"相關的內容,通過資料庫模糊匹配%solr%可以查到,數量少的話查詢速度還挺可觀,如果資料量到達百萬級千萬級甚至更多,可能查出來得猴年馬月了。
而solr用的倒排索引可以解決這一問題。
什麼是倒排索引,先說下正排索引。
假如我有部分資料
文件id | 文件內容 |
1 | solr的使用以及如何在java中使用solr實現搜尋功能 |
2 | solr是一個獨立的企業級搜尋應用伺服器 |
3 | 倒排索引和正排索引 |
4 | 搜尋引擎 |
假如我要搜尋solr,通過正排索引就是文件id作為索引,找到內容包含solr的文件。文件數量多了之後極大增加的搜尋時間。
而倒排索引是將文件內容分詞後建立索引。
單詞內容 | 文件id |
solr | 1,2 |
java | 1 |
搜尋 | 1,2,4 |
索引 | 3 |
伺服器 | 2 |
此時我要搜尋solr時直接通過單詞內容索引,找到文件id列表,在按照文件出現的頻次等內容計算權重然後返回。
3、solr在windows下的安裝與配置
3.1、solr的下載和安裝
前往官網下載solr,我下載的版本是solr7.7.2 http://lucene.apache.org/solr/
解壓後進入cmd進入bin目錄執行 solr start命令,命令列顯示如下,啟動成功,預設埠8983,也可通過-p指定埠啟動
此時可以開啟solr管理頁面,瀏覽器輸入http://localhost:8983/solr
3.2 solr core的建立
core就是solr的一個例項,一個solr服務下可以有多個core,每個core下都有自己的索引庫和與之相應的配置檔案。命令列和管理頁面都可以建立core,在這我通過命令列建立。
在命令列輸入solr create -c "自定義core_name",如圖建立成功。
3.3匯入資料
- 配置資料來源
在mysql中新增表和資料,在這裡我新增了表city,並新增了一些城市的資料。
在\server\solr\test_core(自定義的core名)\conf下新建dataConfig.xml (名字可以自己取)。
標籤簡介:
dataSource:資料庫連線的基本配置
entity:資料庫中的表
field:表中欄位與下文中配置的schema欄位一致。
<?xml version="1.0" encoding="UTF-8" ?> <dataConfig>
<dataSource driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/my_test" user="root" password="root"/> <document> <entity name="city" query="select cid,city,pid from city"> <field column="cid" name="cid"/> <field column="city" name="city"/> <field column="pid" name="pid"/> </entity> </document> </dataConfig>
- 配置schema
schema是用來告訴solr如何建立索引的,他的配置圍繞著一個schema配置檔案,這個配置檔案決定著solr如何建立索引,每個欄位的資料型別,分詞方式等,新版本的schema配置檔案的名字叫做managed-schema。
裡面標籤簡介:
fieldType:為field定義型別,最主要作用是定義分詞器,分詞器決定著如何從文件中檢索關鍵字。
analyzer:他是fieldType下的子元素,分詞器。
filed:建立索引用的欄位,如果想要這個欄位生成索引需要配置他的indexed屬性為true,stored屬性為true表示儲存該索引。
<field name="cid" type="pint" indexed="true" stored="true"/> <field name="city" type="String" indexed="true" stored="true"/> <field name="pid" type="pint" indexed="true" stored="true"/>
在\server\solr\test_core(自定義的core名)\conf下開啟managed-schema
- 配置資料匯入處理器
在\server\solr\test_core(自定義的core名)\conf下開啟solrconfig.xml。新增以下內容,dataConfig,xml即為上文中配置的資料來源。
<requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler"> <lst name="defaults"> <!-- 配置檔案的路徑應該也可以使用絕對路徑 --> <str name="config">dataConfig.xml</str> </lst> </requestHandler>
- 匯入jar包
資料庫驅動的jar:mysql-connector-java-8.0.11.jar (注意這裡jar包的版本要根據你資料庫的版本來我的資料庫是mysql8.0)
data-import的jar:在根目錄\dist下有這兩個包solr-dataimporthandler-7.7.2.jar和solr-dataimporthandler-extras-7.7.2.jar。
複製這三個jar包到\server\solr-webapp\webapp\WEB-INF\lib下
- 匯入資料
以上配置結束後重新啟動solr(命令列輸入solr restart -p 8983)。登入solr管理頁面http://localhost:8983/solr,可以看到選擇core的時候可以選擇之前建立的test_core
選擇Dataimport選項,勾選clean、commit、 debug,Entiry選擇city,點選Execute
執行成功後可以看見右邊記錄數,以及response下的具體資料。
關於solr管理平臺的其他一些功能這裡暫不詳述,有興趣的同學可以自行百度。
3.4查詢
選擇Query功能,可以查詢資料。
3.5分詞
至此基本的查詢已經實現了,但還沒實現分詞效果。
通過分詞分析器可以看出這一句話沒有分詞。
配置ik分詞器。下載ik-analyzer-solr7-7.x.jar放入\server\solr-webapp\webapp\WEB-INF\lib中。
然後在WEB-INF資料夾下新建一個"classes"檔案,從ik-analyzer-solr7-7.x.jar中找到配置檔案IKAnalyzer.cfg.xml中賦值到classes目錄下。(我是從jar包解壓獲取的)到classes目錄下。然後配置managed-schema中新增ik分詞器的配置,並且把field city的型別改為ik_word這樣搜尋的時候才會應用分詞。
<fieldType name="ik_word" 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>
重啟solr,開啟管理介面分詞分析,可以看到一句話被分成了好幾個單詞。
查詢介面用這句話查詢,可以看出查到了重慶市和北京市這兩個記錄。
至此分詞查詢也告一段落,下一章會和大家一起看看在java中使用solr。
4、相關問題Q&A
- Q:在Dataimport的頁面下匯入資料時,一直匯入不成功,也看不到報錯資訊。
A:勾選下列dubug選項,執行。右邊會有具體報錯資訊,Unable to load authentication plugin 'caching_sha2_password'。
mysql-5.7版本是:default_authentication_plugin=mysql_native_password ,mysql-8.x版本是:default_authentication_plugin=caching_sha2_password
而mysql-connector-java-5.7.jar的版本識別不了mysql_native_password的密碼規則,替換jar包為8.0.11即可。
本人只是個小白,以上只是個人拙見,如果有問題還請大家指出,有更好的想法歡迎大家留言,一起進步,謝謝!