添加中文分词(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
http://10.41.2.82:8080/solr/#/inspur-shard1-replica1/analysis
【
出错:
原因:
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);
}
}
结果: