首先介紹一下solr:
Apache Solr (讀音: SOLer) 是一個開源、高性能、採用Java開發、基於Lucene的全文搜索服務器,文檔通過Http利用XML加到一個搜索集合中,查詢該集合也是通過
http收到一個XML/JSON響應來實現。Solr 中存儲的資源是以 Document 爲對象進行存儲的。每個文檔由一系列的 Field 構成,每個 Field 表示資源的一個屬性。Solr 中的每個 Document 需要有能唯一標識其自身的屬性,默認情況下這個屬性的名字是
id,在 Schema 配置文件(schema.xml)中使用:<uniqueKey>id</uniqueKey>
進行描述。solr有兩個核心文件,solrconfig.xml和schema.xml。solrconfig.xml是solr的基礎文件,裏面配置了各種web請求處理器、請求響應處理器、日誌、緩存等;schema.xml配置映射了各種數據類型的索引方案,分詞器的配置、索引文檔中包含的字段也在此配置。
工作中主要用來分詞和搜索,簡單的工作原理是:利用分詞器對數據源進行分詞處理,然後根據分詞結果建立索引庫;查詢的時候,利用分詞器對查詢語句進行分詞,根據查詢語句分詞的結果在索引庫中進行匹配,最後返回結果。
廢話少說,下面開始solr之旅吧:
一.安裝JDK和Tomcat
(2):安裝tomcat,下載tomcat安裝包,解壓到apache-tomcat目錄下
修改tomcat安裝目錄下的conf目錄的server.xml
找到<Connector port="8080" .../>,加入URIEncoding="UTF-8",爲了支持中文。
設置Java和tomcat環境變量
上面兩步比較簡單,這裏就只簡單描述一下,不明白的可以網上查資料。
二. 安裝solr
下載solr包,http://labs.renren.com/apache-mirror/lucene/solr/3.5.0/apache-solr-3.5.0.zip
解壓縮到apache-solr目錄,把apache-solr/dist目錄下的apache-solr-3.5.0.war 複製到$TOMCAT_HOME/webapps目錄下,重命名爲solr.war
複製apache-solr/example/solr到tomcat根目錄下(如果你想配置多core(實例),就複製apache-solr/example/multicore到tomcat根目錄下,不用複製solr了),作爲solr/home,以後也可以往該目錄添加 core,每個core下面都可以有自己的配置文件。
在apache-tomcat/conf/Catalina/localhost/下創建solr.xml(跟webapps下的solr項目同名),指定solr.war和solr/home的位置,讓tomcat啓動時就自動加載該應用。
solr.xml內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="/home/zhoujh/java/apache-tomcat7/webapps/solr.war" debug="0" crossContext="true" >
<Environment name="solr/home" type="java.lang.String" value="/home/zhoujh/java/apache-tomcat7/solr" override="true" />
</Context>
然後在tomcat的bin目錄下執行./startup.sh,啓動tomcat
在地址欄訪問http://localhost:8080/solr/
將會出現solr歡迎界面和admin入口
注:如果出現org.apache.solr.common.SolrException: Error loading class 'solr.VelocityResponseWriter' 異常,最簡單的解決方法:找到$TOMCAT_HOME/solr/conf/solrconfig.xml,把<queryResponseWriter name="velocity" class="solr.VelocityResponseWriter" enable="${solr.velocity.enabled:true}"/>註釋掉或者enable:false即可。如果一切順利的話,現在可以看到solr的web管理界面了。不過要想實現分詞的功能,得安裝一箇中文分詞器,這裏推薦IKAnalyzer或mmseg4j。
IKAnalyzer是一個開源的,基於java語言開發的輕量級的中文分詞工具包,採用了特有的“正向迭代最細粒度切分算法“,具有60萬字/秒的高速處理能力,採用了多子處理器分析模式,支持:英文字母(IP地址、Email、URL)、數字(日期,常用中文數量詞,羅馬數字,科學計數法),中文詞彙(姓名、地名處理)等分詞處理。優化的詞典存儲,更小的內存佔用。支持用戶詞典擴展定。
mmseg4j 用 Chih-Hao Tsai 的 MMSeg 算法(http://technology.chtsai.org/mmseg/ )實現的中文分詞器,並實現 lucene 的 analyzer 和 solr 的TokenizerFactory 以方便在Lucene和Solr中使用。MMSeg 算法有兩種分詞方法:Simple和Complex,都是基於正向最大匹配。Complex 加了四個規則過慮。官方說:詞語的正確識別率達到了 98.41%。mmseg4j 已經實現了這兩種分詞算法。
三. 配置中文分詞器
下面分別安裝這兩個中文分詞器,當然選擇安裝其中一個也是可以的。
(1)安裝IKAnalyzer
下載地址: http://code.google.com/p/ik-analyzer/downloads/list
在當前目錄下新建IKAnalyzer目錄,解壓到該目錄下:unzip IKAnalyzer2012_u5.zip -d ./IKAnalyzer
把IKAnalyzer目錄下的IKAnalyzer2012.jar文件拷貝到 $TOMCAT_HOME/webapps/solr/WEB-INF/lib/下
配置schema.xml,編輯$TOMCAT_HOME/solr/conf/schema.xml,在文件中添加下面這個fieldtype
注:下面的代碼中多了很多“<span style="font-size: x-small;">”標籤,這個是設置字體時iteye編輯器自己生成的。
- <span style="font-size: x-small;"><span style="font-size: x-small;"><span style="font-size: small;"><fieldType name="text" class="solr.TextField" positionIncrementGap="100">
- <analyzer type="index">
- <tokenizer class = "org.wltea.analyzer.solr.IKTokenizerFactory" isMaxWordLength="false" />
- <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
- <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1" />
- <filter class="solr.LowerCaseFilterFactory" />
- <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt" />
- <filter class="solr.RemoveDuplicatesTokenFilterFactory" />
- </analyzer>
- <analyzer type="query">
- <tokenizer class = "org.wltea.analyzer.solr.IKTokenizerFactory" isMaxWordLength="true" />
- <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" />
- <filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" />
- <filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0" splitOnCaseChange="1" />
- <filter class="solr.LowerCaseFilterFactory" />
- <filter class="solr.EnglishPorterFilterFactory" protected="protwords.txt" />
- <filter class="solr.RemoveDuplicatesTokenFilterFactory" />
- </analyzer>
- </fieldType></span></span></span>
添加一個索引字段field,並應用上面配置的fieldtype
- <span style="font-size: x-small;"><span style="font-size: x-small;"><span style="font-size: small;"><field name="game_name" type="text" indexed="true" stored="true" required="true" /> </span></span></span>
然後找到這一句:<defaultSearchField>text</defaultSearchField>把它改成<defaultSearchField>game_name</defaultSearchField>
在瀏覽器打開http://localhost:8080/solr/admin/analysis.jsp,就可以進行分詞處理了。
IKAnalyzer添加自定義分詞詞典:詞典文件格式爲無BOM的UTF-8編碼的文本文件,文件擴展名不限,一次可以添加多個詞庫,每個詞庫以";"分開。把IKAnalyzer目錄下的IKAnalyzer.cfg.xml和stopword.dic拷貝到$TOMCAT_HOME/webapps/solr/WEB_INF/classes目錄下,可以自己新建一個mydic.dic文件,然後在IKAnalyzer.cfg.xml裏進行配置。
(2)安裝mmseg4j
下載地址:http://code.google.com/p/mmseg4j/downloads/list
在當前目錄下新建mmseg4j目錄,解壓到該目錄下:unzip mmseg4j-1.8.5.zip -d ./mmseg4j
把mmseg4j目錄下的mmseg4j-all-1.8.5.jar文件拷貝到 $TOMCAT_HOME/webapps/solr/WEB-INF/lib/下
配置schema.xml,編輯$TOMCAT_HOME/solr/conf/schema.xml,在文件中添加下面這個fieldtype
- <span style="font-size: x-small;"><span style="font-size: x-small;"><span style="font-size: small;"><fieldtype name="textComplex" class="solr.TextField" positionIncrementGap="100">
- <analyzer>
- <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="/home/zhoujh/java/apache-tomcat7/solr/dict">
- </tokenizer>
- </analyzer>
- </fieldtype>
- <fieldtype name="textMaxWord" class="solr.TextField" positionIncrementGap="100">
- <analyzer>
- <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="max-word" dicPath="/home/zhoujh/java/apache-tomcat7/solr/dict">
- </tokenizer>
- </analyzer>
- </fieldtype>
- <fieldtype name="textSimple" class="solr.TextField" positionIncrementGap="100">
- <analyzer>
- <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="simple" dicPath="/home/zhoujh/java/apache-tomcat7/solr/dict">
- </tokenizer>
- </analyzer>
- </fieldtype></span></span></span>
注意:dicPath的值改成你自己機器上相應的目錄。
然後修改之前添加的filed,讓其使用mmseg4j分詞器
- <span style="font-size: x-small;"><span style="font-size: x-small;"><span style="font-size: small;"><field name="game_name" type="textComplex" indexed="true" stored="true" required="true" /> </span></span></span>
配置mmseg4j分詞詞典:MMSEG4J的詞庫是可以動態加載的,詞庫的編碼必須是UTF-8,mmseg4j 默認從當前目錄下的 data 目錄讀取上面的文件,當然也可以指定別的目錄,比如我就放在自定義的dict目錄下。自定義詞庫文件名必需是 "words" 爲前綴和 ".dic" 爲後綴。如:/data/words-my.dic。
這裏直接把mmseg4j/data目錄下的所有.dic文件拷貝到$TOMCAT_HOME/solr/dict目錄下。共有:4個dic文件,chars.dic、units.dic、 words.dic、 words-my.dic。下面簡單解釋一下這幾個文件的作用。
1、chars.dic,是單個字,和對應的頻率,一行一對,字在全面,頻率在後面,中間用空格分開。這個文件的信息是 complex 模式要用到的。在最後一條過慮規則中使用了頻率信息。
2、units.dic,是單位的字,如:分、秒、年。
3、words.dic,是核心的詞庫文件,一行一條,不需要其它任何數據(如詞長)。
4、words-my.dic,是自定義詞庫文件
在瀏覽器打開http://localhost:8080/solr/admin/analysis.jsp,就可以看到分詞效果了。
現在,這兩種分詞方法都已配置好了,想用哪種就把查詢的filed的type設置成哪種。
四. 導入文檔數據
現在添加文本搜索的功能,首先導入數據源。
切換到/home/zhoujh/java/solr/apache-solr/example/exampledocs目錄下,該目錄下有很多xml文件,隨便copy一個,改名位game_data.xml。如:cp hd.xml game_data.xml,修改內容如下:
- <span style="font-size: x-small;"><span style="font-size: x-small;"><span style="font-size: small;"><add>
- <doc>
- <field name="id">1</field>
- <field name="game_name">魔獸世界</field>
- </doc>
- <doc>
- <field name="id">2</field>
- <field name="game_name">仙劍</field>
- </doc>
- <doc>
- <field name="id">3</field>
- <field name="game_name">傳奇</field>
- </doc>
- <doc>
- <field name="id">4</field>
- <field name="game_name">極品飛車</field>
- </doc>
- <doc>
- <field name="id">5</field>
- <field name="game_name">軒轅劍</field>
- </doc>
- </add></span></span></span>
注意:該xml文件必須是UTF-8格式的。
然後提交到solr,在 /home/zhoujh/java/solr/apache-solr/example/exampledocs目錄下執行命令:
[zhoujh@alexzhou exampledocs]$ java -Durl=http://localhost:8080/solr/update -Dcommit=yes -jar post.jar game_data.xml
如果輸出下面的信息,則導入成功。注:xml文件中要有game_name這個field。如果出錯,到$TOMCAT_HOME/logs/下看catalinaxxx.log日誌信息
SimplePostTool: version 1.4
SimplePostTool: POSTing files to http://localhost:8080/solr/update..
SimplePostTool: POSTing file game_data.xml
SimplePostTool: COMMITting Solr index changes..
檢測是否有數據:http://localhost:8080/solr/select/?q=*:*,如果輸出信息如下,就成功了。
- <span style="font-size: x-small;"><span style="font-size: small;"><response>
- <lst name="responseHeader">
- <int name="status">0</int>
- <int name="QTime">0</int>
- <lst name="params">
- <str name="indent">on</str>
- <str name="start">0</str>
- <str name="q">*:*</str>
- <str name="rows">10</str>
- <str name="version">2.2</str>
- </lst>
- </lst>
- <result name="response" numFound="5" start="0">
- <doc>
- <str name="game_name">魔獸世界</str>
- <str name="id">1</str>
- </doc>
- <doc>
- <str name="game_name">仙劍</str>
- <str name="id">2</str>
- </doc>
- <doc>
- <str name="game_name">傳奇</str>
- <str name="id">3</str>
- </doc>
- <doc>
- <str name="game_name">極品飛車</str>
- <str name="id">4</str>
- </doc>
- <doc>
- <str name="game_name">軒轅劍</str>
- <str name="id">5</str>
- </doc>
- </result>
- </response></span></span>
不過在現實工作中,一般利用數據庫作爲數據源,下面我們來配置solr連接數據庫源。
五. solr從數據庫導入數據
(1)安裝mysql,
安裝完後執行以下命令:啓動mysql服務,進入mysql,創建數據庫kw_game,創建表game,導入數據
- <span style="font-size: x-small;"><span style="font-size: small;">sudo /etc/init.d/mysqld start
- mysql -u root -p
- create database kw_game;
- use kw_game;
- create table game(id int primary key auto_increment,game_name varchar(100),add_time datetime);
- insert into game(game_name,add_time) values("魔獸世界",now());
- insert into game(game_name,add_time) values("魔獸爭霸",now());
- insert into game(game_name,add_time) values("傳奇世界",now());</span></span>
(2)下載 mysql-connector-java-xx-bin.jar(驅動程序)
把 mysql-connector-java-5.1.20-bin.jar複製到~/java/apache-tomcat7/webapps/solr/WEB-INF/lib/目錄下
cp mysql-connector-java-5.1.20-bin.jar ~/java/apache-tomcat7/webapps/solr/WEB-INF/lib/
(2)配置solrconfig.xml,添加一個requestHandler
- <span style="font-size: x-small;"><span style="font-size: x-small;"><span style="font-size: small;"><requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
- <lst name="defaults">
- <str name="config">game-data-config.xml</str>
- </lst>
- </requestHandler></span></span></span>
(3)新建一個數據源配置文件game-data-config.xml,內容如下
- <span style="font-size: x-small;"><span style="font-size: x-small;"><span style="font-size: small;"><?xml version="1.0" encoding="UTF-8"?>
- <dataConfig>
- <dataSource type="JdbcDataSource"
- driver="com.mysql.jdbc.Driver"
- url="jdbc:mysql://localhost:3306/game_db"
- user="root"
- password="123456"/>
- <document name="doc">
- <entity name="game" query="select * from game"
- deltaImportQuery="select * from game where id='${dataimporter.delta.id}'"
- deltaQuery="select id from game where add_time > '${dataimporter.last_index_time}'">
- <field column="id" name="id" />
- <field column="game_name" name="game_name" /><field column="add_time" name="add_time" />
- </entity>
- </document>
- </dataConfig></span></span></span>
注: deltaImportQuery、deltaQuery:增量更新時用到,因爲在schema.xml中已經有game_name和id字段了,只需在schmema.xml添加add_time字段,格式爲date或者string。
在瀏覽器輸入下面兩個地址,導入數據創建索引。
更新全部: http://localhost:8080/solr/dataimport?command=full-import
增量更新: http://localhost:8080/solr/dataimport?command=delta-import
然後檢測是否有數據:http://localhost:8080/solr/select/?q=*:*,現在頁面上出現的就是你數據庫裏的數據了。
注:如果出現了下面異常:
Error loading class 'org.apache.solr.handler.dataimport.DataImportHandler
是solrconfig.xml文件中<lib dir="xx/dist/ regex="" /> dir的路徑錯了,改成你電腦上正確的位置就ok了~~
六. 配置多個實例
最後簡單介紹一下如何配置多個實例,編輯$TOMCAT_HOME/solr/solr.xml
- <span style="font-size: x-small;"><span style="font-size: small;"><cores adminPath="/admin/cores">
- <core name="game" instanceDir="game" /> <core name="game2" instanceDir="game2" />
- </cores></span></span>
此時訪問的時候必須得在solr後加上各實例的名稱
http://localhost:8080/solr/game/admin
http://localhost:8080/solr/game2/admin