添加中文分詞(mmseg4j)
1.下載mmseg4j
2.下載sogou的中文詞庫
3.將中文分詞的jar包拷貝到solr的server的lib目錄下
3.1由於mmseg4j-1.9.1與solr4.9結合時有一個小bug,需要先修改
修改類:com.chenlb.mmseg4j.analysis.MMSegTokenizer
方法:public void reset() throws IOException
修改後的方法如下:
public void reset() throws IOException {
//lucene 4.0
//org.apache.lucene.analysis.Tokenizer.setReader(Reader)
//setReader 自動被調用, input 自動被設置。
//需要先調用super.reset();否則會報錯
super.reset();
mmSeg.reset(input);
}
3.2將修改後的class文件放入mmseg4j-1.9.1的jar包:mmseg4j-analysis-1.9.1.jar中
com.chenlb.mmseg4j.analysis.MMSegTokenizer.class
3.3將修改後的中文分詞的jar包拷貝到所有solr的server(%SOLR_HOME%)的lib目錄下
注意:這裏%SOLR_HOME%=/usr/local/search/solr/solrhome/data/solr/collection1/
cp /opt/mmseg4j-analysis-1.9.1.jar /usr/local/search/solr/solrhome/data/solr/collection1/lib/
cp /opt/mmseg4j-core-1.9.1.jar /usr/local/search/solr/solrhome/data/solr/collection1/lib/
cp /opt/mmseg4j-solr-1.9.1.jar /usr/local/search/solr/solrhome/data/solr/collection1/lib/
4.將中文分詞的配置信息添加到solr的schema.xml(%SOLR_HOME%/conf/schema.xml)的FieldType中
vi /usr/local/search/solr/solrhome/data/solr/collection1/conf/schema.xml
<fieldType name="textComplex" class="solr.TextField" positionIncrementGap="100" >
<analyzer>
<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" />
</analyzer>
</fieldType>
<fieldType name="textMaxWord" class="solr.TextField" positionIncrementGap="100" >
<analyzer>
<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="max-word" />
</analyzer>
</fieldType>
<fieldType name="textSimple" class="solr.TextField" positionIncrementGap="100" >
<analyzer>
<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="simple" />
</analyzer>
</fieldType>
<fieldType name="textComplex" class="solr.TextField" positionIncrementGap="100" >
<analyzer>
<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="dic"/>
</analyzer>
</fieldType>
<fieldType name="textMaxWord" class="solr.TextField" positionIncrementGap="100" >
<analyzer>
<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="max-word" dicPath="dic"/>
</analyzer>
</fieldType>
<fieldType name="textSimple" class="solr.TextField" positionIncrementGap="100" >
<analyzer>
<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="simple" dicPath="n:/OpenSource/apache-solr-1.3.0/example/solr/my_dic"/>
</analyzer>
</fieldType>
dicPath 指定詞庫位置(每個MMSegTokenizerFactory可以指定不同的目錄,當是相對目錄時,是相對 solr.home 的目錄),mode 指定分詞模式(simple|complex|max-word,默認是max-word)。
【
注意:這裏 solr.home =/usr/local/search/solr/solrhome/data/solr/collection1/
】
【
在 com.chenlb.mmseg4j.analysis包裏擴展lucene analyzer。MMSegAnalyzer默認使用max-word方式分詞(還有:ComplexAnalyzer, SimplexAnalyzer, MaxWordAnalyzer)。
在 com.chenlb.mmseg4j.solr包裏擴展solr tokenizerFactory。 1.9.0 可以不用 dicPath 參數,可以使用 mmseg4j-core-1.9.0.jar 裏的 words.dic 在 solr的 schema.xml 中定義 field type即可:
】
5.配置solr的schema.xml(%SOLR_HOME%/conf/schema.xml)的field元素
vi /usr/local/search/solr/solrhome/data/solr/collection1/conf/schema.xml
<field name="my_complex_content" type="textComplex" indexed="true" stored="true"/>
<field name="my_maxword_content" type="textMaxWord" indexed="true" stored="true"/>
<field name="my_simple_content" type="textSimple" indexed="true" stored="true"/>
6.使用sogou中文詞庫
將sogou的詞庫放在%SOLR_HOME%目錄下
修改fieldType的配置,加入dicPath屬性
修改後的fieldType配置如下:
7.重啓各個solr節點
/usr/local/search/tomcat/apache-tomcat-7.0.55/bin/shutdown.sh
/usr/local/search/tomcat/apache-tomcat-7.0.55/bin/startup.sh
【
可能出現的問題:
問題原因:
兩個core共用了相同的數據目錄,這樣兩個core的鎖文件write.lock就都在一個數據目錄下,當一個core啓動時佔用了write.lock,另一個core就無法再去佔用write.lock,因此就會啓動失敗。
解決辦法:
刪除原有的core, 爲每個core單獨指定數據目錄
重新創建core:
curl "http://10.41.2.82:8080/solr/admin/cores?action=CREATE&name=inspur-shard1-replica1&instanceDir=/usr/local/search/solr/solrhome/data/solr/inspur-shard1-replica1&dataDir=/usr/local/search/solr/solrhome/data/solr/inspur-shard1-replica1/data&collection=inspur&shard=shard1"
curl "http://10.41.2.83:8080/solr/admin/cores?action=CREATE&name=inspur-shard1-replica2&instanceDir=/usr/local/search/solr/solrhome/data/solr/inspur-shard1-replica2&dataDir=/usr/local/search/solr/solrhome/data/solr/inspur-shard1-replica2/data&collection=inspur&shard=shard1"
curl "http://10.41.2.84:8080/solr/admin/cores?action=CREATE&name=inspur-shard2-replica1&instanceDir=/usr/local/search/solr/solrhome/data/solr/inspur-shard2-replica1&dataDir=/usr/local/search/solr/solrhome/data/solr/inspur-shard2-replica1/data&collection=inspur&shard=shard2"
curl "http://10.41.2.86:8080/solr/admin/cores?action=CREATE&name=inspur-shard2-replica2&instanceDir=/usr/local/search/solr/solrhome/data/solr/inspur-shard2-replica2&dataDir=/usr/local/search/solr/solrhome/data/solr/inspur-shard2-replica2/data&collection=inspur&shard=shard2"
】
http://10.41.2.86:8080/solr/admin
8.測試
8.1Web UI
【
出錯:
原因:
mmseg4j-1.9.1中文分詞器僅支持solr-4.3.1,還沒有支持到solr-4.9
解決辦法:
修改類:com.chenlb.mmseg4j.solr.MMSegTokenizerFactory.java
將
import org.apache.lucene.util.AttributeSource.AttributeFactory;
改爲:
import org.apache.lucene.util.AttributeFactory;
將修改後的類com.chenlb.mmseg4j.solr.MMSegTokenizerFactory.class
放入包mmseg4j-solr-1.9.1.jar中
重啓solr的tomcat
】
8.2solrj
8.2.1創建索引
/*
* 創建索引
* 測試中文
*/
public static void createIndexWithZHCN( SolrServer server) throws SolrServerException, IOException {
SolrInputDocument doc=new SolrInputDocument();
doc.addField("id", "zhcn1", 1.0f);
doc.addField("my_complex_content", "數據挖掘與數據化運營實戰", 1.0f);
doc.addField("my_maxword_content", "數據挖掘與數據化運營實戰");
doc.addField("my_simple_content", "數據挖掘與數據化運營實戰");
server.add(doc);
server.commit();
}
8.2.2查詢索引
/**
* 搜索
* 測試中文
* @param server
* @throws SolrServerException
*/
public static void searchIndexWithZHCN(SolrServer server) throws SolrServerException{
SolrQuery query=new SolrQuery();
query.setQuery("my_complex_content:挖掘");
SortClause sortClause=new SortClause("my_maxword_content",SolrQuery.ORDER.desc);
query.addSort(sortClause);
QueryResponse resp=server.query(query);
SolrDocumentList docs=resp.getResults();
for(SolrDocument doc:docs){
String id=(String)doc.get("id");
String my_complex_content=(String)doc.get("my_complex_content");
String my_maxword_content=(String)doc.get("my_maxword_content");
String my_simple_content=(String)doc.get("my_simple_content");
System.out.println("id="+id+"\t my_complex_content="+my_complex_content+"\t my_maxword_content="+my_maxword_content+"\t my_simple_content="+my_simple_content);
}
}
結果: