最近接觸搜索相關的內容,所以熟悉下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即可。
本人只是個小白,以上只是個人拙見,如果有問題還請大家指出,有更好的想法歡迎大家留言,一起進步,謝謝!