设为首页 收藏本站
查看: 2446|回复: 0

[经验分享] 用solr从数据库建立中文Lucene索引

[复制链接]

尚未签到

发表于 2016-12-16 08:46:45 | 显示全部楼层 |阅读模式

用solr从数据库建立中文Lucene索引

  




Solr是一个基于Lucene java库的企业级搜索服务器,运行在Servlet容器中。


1.  下载solr: http://www.apache.org/dyn/closer.cgi/lucene/solr/


    当前最新版是1.4


    解压到一个目录中,假设是solrpath


2.  添加Handler


    编辑solrpath/example/solr/conf文件夹下的solrconfig.xml文件,在config元素中添加

   
Xml代码   DSC0000.png DSC0001.gif






  • <
    requestHandler
     
    name
    =
    "/dataimport"
     
    class
    =
    "org.apache.solr.handler.dataimport.DataImportHandler"
    >
      


  •     <
    lst
     
    name
    =
    "defaults"
    >
      


  •       <
    str
     
    name
    =
    "config"
    >
    data-config.xml
    </
    str
    >
      


  •     </
    lst
    >
      


  • </
    requestHandler
    >
      




    <requestHandler name="/dataimport" class="org.apache.solr.handler.dataimport.DataImportHandler">
<lst name="defaults">
<str name="config">data-config.xml</str>
</lst>
</requestHandler>

  



3.  在此文件夹中新建一个data-config.xml文件,内容如下


    detail列是一个clob类型的,要用到ClobTransformer,这是1.4版本中才有的


    column="DETAIL" clob="true"中的列名DETAIL一定要大写,要不会不起作用

Xml代码  






  • <
    dataConfig
    >
      


  •   <
    dataSource
     
    type
    =
    "JdbcDataSource"
       


  •               driver
    =
    "com.mysql.jdbc.Driver"
      


  •               url
    =
    "jdbc:mysql://localhost/dbname"
       


  •               user
    =
    "user-name"
       


  •               password
    =
    "password"
    />
      


  •   <
    document
    >
      


  •     <
    entity
     
    name
    =
    "myentyty"
     
    transformer
    =
    "ClobTransformer"
      


  •         query
    =
    "select id, title, detail from mytable"
    >
      


  •         <
    field
     
    column
    =
    "DETAIL"
     
    clob
    =
    "true"
    />
      


  •     </
    entity
    >
      


  •   </
    document
    >
      


  • </
    dataConfig
    >
      




<dataConfig>
<dataSource type="JdbcDataSource"
driver="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost/dbname"
user="user-name"
password="password"/>
<document>
<entity name="myentyty" transformer="ClobTransformer"
query="select id, title, detail from mytable">
<field column="DETAIL" clob="true"/>
</entity>
</document>
</dataConfig>
  



4.  修改schema.xml,找到<fieldType name="text",将分词器修改为中文分词器,这里用的是包装过的Paoding分词,这个东西好像已经不更新了,以后看看IKAnalyzer吧。

Xml代码  






  •  
    <
    fieldType
     
    name
    =
    "text"
     
    class
    =
    "solr.TextField"
     
    positionIncrementGap
    =
    "100"
    >
        


  •     <
    analyzer
     
    type
    =
    "index"
    >
        


  •         <
    tokenizer
     
    class
    =
    "net.paoding.analysis.analyzer.ChineseTokenizerFactory"
     
    mode
    =
    "most-words"
    />
        


  •         <
    filter
     
    class
    =
    "solr.StopFilterFactory"
     
    ignoreCase
    =
    "true"
     
    words
    =
    "stopwords.txt"
    />
        


  •         <
    filter
     
    class
    =
    "solr.WordDelimiterFilterFactory"
     
    generateWordParts
    =
    "1"
     
    generateNumberParts
    =
    "1"
     
    catenateWords
    =
    "1"
     
    catenateNumbers
    =
    "1"
     
    catenateAll
    =
    "0"
    />
        


  •         <
    filter
     
    class
    =
    "solr.LowerCaseFilterFactory"
    />
        


  •         <
    filter
     
    class
    =
    "solr.RemoveDuplicatesTokenFilterFactory"
    />
        


  •     </
    analyzer
    >
        


  •     <
    analyzer
     
    type
    =
    "query"
    >
        


  •         <
    tokenizer
     
    class
    =
    "net.paoding.analysis.analyzer.ChineseTokenizerFactory"
     
    mode
    =
    "most-words"
    />
                        


  •         <
    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"
    />
        


  •         <
    filter
     
    class
    =
    "solr.LowerCaseFilterFactory"
    />
        


  •         <
    filter
     
    class
    =
    "solr.RemoveDuplicatesTokenFilterFactory"
    />
        


  •     </
    analyzer
    >
        


  • </
    fieldType
    >
      




    <fieldType name="text" class="solr.TextField" positionIncrementGap="100">  
<analyzer type="index">  
<tokenizer class="net.paoding.analysis.analyzer.ChineseTokenizerFactory" mode="most-words"/>  
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt"/>  
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0"/>  
<filter class="solr.LowerCaseFilterFactory"/>  
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>  
</analyzer>  
<analyzer type="query">  
<tokenizer class="net.paoding.analysis.analyzer.ChineseTokenizerFactory" mode="most-words"/>                  
<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"/>  
<filter class="solr.LowerCaseFilterFactory"/>  
<filter class="solr.RemoveDuplicatesTokenFilterFactory"/>  
</analyzer>  
</fieldType>
  



   原来的schema.xml中没有的字段自己添加上。schema.xml默认是UTF-8编码,添加中文注释要在UTF-8编码下添加,要不会报错的

  
Xml代码  






  • <
    field
     
    name
    =
    "detail"
     
    type
    =
    "text"
     
    indexed
    =
    "true"
     
    stored
    =
    "true"
     
    />
      


  • <!-- 添加到默认的查询字段,可根据需要修改 -->
      


  • <
    copyField
     
    source
    =
    "title"
     
    dest
    =
    "text"
    />
      


  • <
    copyField
     
    source
    =
    "detail"
     
    dest
    =
    "text"
    />
      




   <field name="detail" type="text" indexed="true" stored="true" />
<!-- 添加到默认的查询字段,可根据需要修改 -->
<copyField source="title" dest="text"/>
<copyField source="detail" dest="text"/>
  



5.  包装Paoding的分词器

Java代码  






  • package
     net.paoding.analysis.analyzer;  


  •   

  • import
     java.io.Reader;  


  • import
     java.util.Map;  


  •   

  • import
     net.paoding.analysis.analyzer.impl.MaxWordLengthTokenCollector;  


  • import
     net.paoding.analysis.analyzer.impl.MostWordsTokenCollector;  


  • import
     net.paoding.analysis.knife.PaodingMaker;  


  •   

  • import
     org.apache.lucene.analysis.Tokenizer;  


  • import
     org.apache.solr.analysis.BaseTokenizerFactory;  


  •   

  • /**
     

  •  * Created by IntelliJ IDEA. 
     

  •  * User: ronghao 
     

  •  * Date: 2007-11-3 
     

  •  * Time: 14:40:59 中文切词 对庖丁切词的封装
     

  •  */
      


  • public
     
    class
     ChineseTokenizerFactory 
    extends
     BaseTokenizerFactory {  


  •     /**
     

  •      * 最多切分 默认模式
     

  •      */
      


  •     public
     
    static
     
    final
     String MOST_WORDS_MODE = 
    "most-words"
    ;  


  •     /**
     

  •      * 按最大切分
     

  •      */
      


  •     public
     
    static
     
    final
     String MAX_WORD_LENGTH_MODE = 
    "max-word-length"
    ;  


  •   

  •     private
     String mode = 
    null
    ;  


  •   

  •     public
     
    void
     setMode(String mode) {  


  •         if
     (mode == 
    null
     || MOST_WORDS_MODE.equalsIgnoreCase(mode) || 
    "default"
    .equalsIgnoreCase(mode)) {  


  •             this
    .mode = MOST_WORDS_MODE;  


  •         } else
     
    if
     (MAX_WORD_LENGTH_MODE.equalsIgnoreCase(mode)) {  


  •             this
    .mode = MAX_WORD_LENGTH_MODE;  


  •         } else
     {  


  •             throw
     
    new
     IllegalArgumentException(
    "不合法的分析器Mode参数设置:"
     + mode);  


  •         }  

  •     }  

  •   

  •     @Override
      


  •     public
     
    void
     init(Map<String, String> args) {  


  •         super
    .init(args);  


  •         setMode(args.get("mode"
    ));  


  •     }  

  •   

  •     public
     Tokenizer create(Reader input) {  


  •         return
     
    new
     PaodingTokenizer2(input, PaodingMaker.make(), createTokenCollector());  


  •     }  

  •   

  •     private
     TokenCollector createTokenCollector() {  


  •         if
     (MOST_WORDS_MODE.equals(mode))  


  •             return
     
    new
     MostWordsTokenCollector();  


  •         if
     (MAX_WORD_LENGTH_MODE.equals(mode))  


  •             return
     
    new
     MaxWordLengthTokenCollector();  


  •         throw
     
    new
     Error(
    "never happened"
    );  


  •     }  

  • }  



package net.paoding.analysis.analyzer;
import java.io.Reader;
import java.util.Map;
import net.paoding.analysis.analyzer.impl.MaxWordLengthTokenCollector;
import net.paoding.analysis.analyzer.impl.MostWordsTokenCollector;
import net.paoding.analysis.knife.PaodingMaker;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.solr.analysis.BaseTokenizerFactory;
/**
* Created by IntelliJ IDEA.
* User: ronghao
* Date: 2007-11-3
* Time: 14:40:59 中文切词 对庖丁切词的封装
*/
public class ChineseTokenizerFactory extends BaseTokenizerFactory {
/**
* 最多切分 默认模式
*/
public static final String MOST_WORDS_MODE = "most-words";
/**
* 按最大切分
*/
public static final String MAX_WORD_LENGTH_MODE = "max-word-length";
private String mode = null;
public void setMode(String mode) {
if (mode == null || MOST_WORDS_MODE.equalsIgnoreCase(mode) || "default".equalsIgnoreCase(mode)) {
this.mode = MOST_WORDS_MODE;
} else if (MAX_WORD_LENGTH_MODE.equalsIgnoreCase(mode)) {
this.mode = MAX_WORD_LENGTH_MODE;
} else {
throw new IllegalArgumentException("不合法的分析器Mode参数设置:" + mode);
}
}
@Override
public void init(Map<String, String> args) {
super.init(args);
setMode(args.get("mode"));
}
public Tokenizer create(Reader input) {
return new PaodingTokenizer2(input, PaodingMaker.make(), createTokenCollector());
}
private TokenCollector createTokenCollector() {
if (MOST_WORDS_MODE.equals(mode))
return new MostWordsTokenCollector();
if (MAX_WORD_LENGTH_MODE.equals(mode))
return new MaxWordLengthTokenCollector();
throw new Error("never happened");
}
}

  


因为新版本的接口可能是变了,还需要对PaodingTokenizer类修改一下,原来是继承TokenStream类,改为继承Tokenizer



Java代码  






  • public
     
    final
     
    class
     PaodingTokenizer2 
    extends
     Tokenizer 
    implements
     Collector {  




public final class PaodingTokenizer2 extends Tokenizer implements Collector {
  



这两个修改的类就放在solr.war中,在压缩包的WEB-INF文件夹中新建classes文件夹,将这两个类连同包层次复制进去就行



6.  将Paoding和数据库驱动放到lib中,进入solrpath/example目录中运行命令


    java -jar start.jar


    进入浏览器,运行


    http://localhost:8983/solr/dataimport?command=full-import


    导入成功后,运行


    http://localhost:8983/solr/admin/


    在搜索框中输入搜索内容进行查询



还有个Paoding的词典文件的问题,一开始是建了个PAODING_DIC_HOME的环境变量,后来删掉也能用了,暂不知道是什么原因,不知它存哪去了

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-314935-1-1.html 上篇帖子: solr二次开发之solrj(转载) 下篇帖子: solr的函数查询_FunctionQuery_总结
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表