前言:公司的solr第一次部署是在4年前,用ruby GEM包部署的,没有IK,没有分词,多字少字没下文,错别字字字不认帐......现在数据量大了,各种东西搜索不到,项目转交到我接手,不说了,全是泪......
怎么办?!
——改!
环境:JDK8,Tomcat8,Solr6,IKAnalyzer,Smartcn,Pinyin4j
以下是我的爬文收藏,有读者用solr6肯定用得上!
第一步:部署Solr6+IK+DIH我不讲了,送上链接:http://download.csdn.net/detail/linzhiqiang0316/9526632,下载里面的东西,改{solrhome}\mynode\conf\data-config.xml里面的数据库链接和entity,改web.xml里面的solrhome目录,改{solrhome}\mynode\conf\solrconfig.xml里面的lib dir目录,启动tomcat就能用了。
第二步:看query查询语句的写法,上链接:http://sling2007.blog.163.com/blog/static/84732713201351311043522/
第三步:中文多字少字,错别字能搜了!拼音搜索,瞎了......咋办?!继续搞,这是我遇到的最坑的地方。
百度爬文无数,找到了解决办法:Smartcn分词+pinyin4j能解决。
好,按照网上的配置改下managed-schema,启动tomcat就报错:error loading class:solr.smartchinesesentencetokenizerfactory。WTF!!!solr自带的包不认自家人!!!
继续百度,stackoverflow有人说改成solr.HMMChineseTokenizerFactory。启动报这个也找不到。不找了!拖出class反编译工具。OK,就是这个了。改成org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory,O了!!
下面给出IK+Smartcn+Pinyin4j的整合XML代码:
<fieldType name="text_pinyin" class="solr.TextField" positionIncrementGap="0"> <analyzer type="index"> <tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/> <filter class="com.shentong.search.analyzers.PinyinTransformTokenFilterFactory" minTermLenght="2" /> <filter class="com.shentong.search.analyzers.PinyinNGramTokenFilterFactory" minGram="1" maxGram="20" /> </analyzer> <analyzer type="query"> <tokenizer class="org.apache.lucene.analysis.cn.smart.HMMChineseTokenizerFactory"/> <filter class="com.shentong.search.analyzers.PinyinTransformTokenFilterFactory" minTermLenght="2" /> <filter class="com.shentong.search.analyzers.PinyinNGramTokenFilterFactory" minGram="1" maxGram="20" /> </analyzer> </fieldType> <field name="pinyin" type ="text_pinyin" indexed ="true" stored ="false" multiValued ="true"/> <fieldType name="text_ik" class="solr.TextField"> <!--索引时候的分词器--> <analyzer type="index"> <tokenizer class="org.wltea.analyzer.util.IKTokenizerFactory" useSmart="true"/> </analyzer> <!--查询时候的分词器--> <analyzer type="query"> <tokenizer class="org.wltea.analyzer.util.IKTokenizerFactory" useSmart="false"/> </analyzer> </fieldType> <field name="name" type="text_ik" indexed="true" stored="true" multiValued="false" /> <copyField source="name" dest="pinyin"/>
记得这是写在managed-schema中的呃!
第四步:一个core索引所有的表,查询的时候显示出表名(知道表名了才知道这个id应该去哪个表里面查)。
开始一直不知道怎么解决,百度有人说用java DTO,不适用于我solr DIH的模式,PASS!!
问群内大神——视图。还是觉得怪异,PASS!
问google solr dih default value,得到了真理!
query的时候:
<?xml version="1.0" encoding="UTF-8"?> <dataConfig> <dataSource type="JdbcDataSource" driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/table" user="root" password="password" batchSize="-1" /> <document> <entity name="videos" pk="id" query="select 'videos'as t_name,videos.* from videos" deltaImportQuery="select 'videos'as t_name,videos.* from videos where videos.id='${dih.delta.id}'" deltaQuery="select 'videos'as t_name,videos.id from videos where videos.updated_at> '${dataimporter.last_index_time}'"> <field column="id" name="id"/> <field column="name" name="name"/> <field column="t_name" name="t_name"/> <field column="updated_at" name="updated_at"/> </entity> <entity name="tv_plays" pk="id" query="select 'tv_plays'as t_name,tv_plays.* from tv_plays" deltaImportQuery="select 'tv_plays'as t_name,tv_plays.* from tv_plays where tv_plays.id='${dih.delta.id}'" deltaQuery="select 'tv_plays'as t_name,tv_plays.id from tv_plays where tv_plays.updated_at> '${dataimporter.last_index_time}'"> <field column="id" name="id"/> <field column="title" name="name"/> <field column="t_name" name="t_name"/> <field column="updated_at" name="updated_at"/> </entity> </document> </dataConfig>
这样t_name就是表名了!
Over!收工!
以下为2017-01-16 23:02时的补充:
晚上下班了回家继续捣鼓solr,发现拼音搜索用NGram更好,匹配的出来的结果更优!
送上配置:
<fieldtype name="ngram" class="solr.TextField" positionIncrementGap="100"> <analyzer> <tokenizer class="solr.NGramTokenizerFactory" minGramSize="1" maxGramSize="1"/> <filter class="solr.LowerCaseFilterFactory"/> </analyzer> </fieldtype> <field name="word" type="ngram" indexed="true" stored="true"/> <copyField source="name" dest="word"/>
以下是我最后修改后的配置,也就是调整到2017-01-16 23:27时形成的配置xml,放弃了IK,改用NGram+pinyin4j!
xml:
<fieldtype name="ngram" class="solr.TextField" positionIncrementGap="100"> <analyzer> <tokenizer class="solr.NGramTokenizerFactory" minGramSize="1" maxGramSize="1"/> <filter class="solr.LowerCaseFilterFactory"/> <filter class="com.shentong.search.analyzers.PinyinTransformTokenFilterFactory" minTermLenght="2" /> <filter class="com.shentong.search.analyzers.PinyinNGramTokenFilterFactory" minGram="1" maxGram="20" /> </analyzer> </fieldtype> <field name="name" type="ngram" indexed="true" stored="true" multiValued="false"/> <field name="t_name" type="string" indexed="true" stored="true" multiValued="false" />
2017-01-16,完结!