zoukankan      html  css  js  c++  java
  • Windows下 建立solr时 出现 问题解答(转 )

    Solr 是一个可供企业使用的、基于 Lucene 的开箱即用的搜索服务器。对Lucene不熟?那么建议先看看下面两篇文档:

    实战Lucene,第 1 部分: 初识 Lucene:http://www.ibm.com/developerworks/cn/java/j-lo-lucene1/

    Lucene加速Web搜索应用程序的开发:http://www.ibm.com/developerworks/cn/web/wa-lucene2/

    一、 solr介绍

    solr是基于Lucene Java搜索库的企业级全文搜索引擎,目前是apache的一个项目。它的官方网址在http://lucene.apache.org/solr/ 。solr需要运行在一个servlet 容器里,例如tomcat5.5solrlucene的上层提供了一个基于HTTP/XMLWeb Services,我们的应用需要通过这个服务与solr进行交互。

    二、 solr安装和配置

    关于solr的安装和配置,这里也有两篇非常好的文档,作者同时也 Lucene Java 项目的提交人和发言人:

    使用Apache Solr实现更加灵巧的搜索:http://www.ibm.com/developerworks/cn/java/j-solr1/index.html

    http://www.ibm.com/developerworks/cn/java/j-solr2/index.html

    下面主要说说需要注意的地方。

    Solr的安装非常简单,下载solrzip包后解压缩将dist目录下的war文件改名为solr.war直接复制到tomcat5.5webapps目录即可。注意一定要设置solr的主位置。有三种方法。我采用的是在tomcat里配置java:comp/env/solr/home的一个JNDI指向solr的主目录(example目录下),建立/tomcat55/conf/Catalina/localhost/solr.xml文件。


    <Context docBase="D:/solr.war" debug="0" crossContext="true" >

       
    <Environment name="solr/home" type="java.lang.String" value="D:/solr/solr" override="true" />

    </Context>

         观察这个指定的solr主位置,里面存在两个文件夹:conf和data。其中conf里存放了对solr而言最为重要的两个配置文件schema.xml和solrconfig.xml。data则用于存放索引文件。

         schema.xml主要包括typesfields和其他的一些缺省设置。

    solrconfig.xml用来配置Solr的一些系统属性,例如与索引和查询处理有关的一些常见的配置选项,以及缓存、扩展等等。

    上面的文档对这两个文件有比较详细的说明,非常容易上手。注意到schema.xml里有一个

    <uniqueKey>url</uniqueKey>

    的配置,这里将url字段作为索引文档的唯一标识符,非常重要。

    三、 加入中文分词

    对全文检索而言,中文分词非常的重要,这里采用了qieqie庖丁分词(非常不错:))。集成非常的容易,我下载的是2.0.4-alpha2版本,其中它支持最多切分和按最大切分。创建自己的一个中文TokenizerFactory继承自solr的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 TokenStream create(Reader input) {

            
    return new PaodingTokenizer(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");

        }

    }

    在schema.xml的字段text配置里加入该分词器。


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

                
    <analyzer type="index">

                    
    <tokenizer class="com.ronghao.fulltextsearch.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="com.ronghao.fulltextsearch.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>

    </types>

        完成后重启tomcat,即可在http://localhost:8080/solr/admin/analysis.jsp

    体验到庖丁的中文分词。注意要将paoding-analysis.jar复制到solr的lib下,注意修改jar包里字典的home。

    四、 与自己应用进行集成

    Solr安装完毕,现在可以将自己的应用与solr集成。其实过程非常的简单,应用增加数据-->根据配置的字段构建add的xml文档-->post至solr/update。

    应用删除数据à根据配置的索引文档唯一标识符构建delete的xml文档-->post至solr/update。

    检索数据à构建查询xml—>get至/solr/select/-->对solr返回的xml进行处理-->页面展现。

    具体的xml格式可以在solr网站找到。另外就是solr支持高亮显示,非常方便。

    关于中文,solr内核支持UTF-8编码,所以在tomcat里的server.xml需要进行配置

    <Connector port="8080" maxHttpHeaderSize="8192" URIEncoding="UTF-8" …/>

    另外,向solr Post请求的时候需要转为utf-8编码。对solr 返回的查询结果也需要进行一次utf-8的转码。检索数据时对查询的关键字也需要转码,然后用“+”连接。


    String[] array = StringUtils.split(query, null0);

            
    for (String str : array) {

                result 
    = result + URLEncoder.encode(str, "UTF-8"+ "+";

            }


    http://www.blogjava.net/ronghao 荣浩原创,转载请注明出处:)
    posted on 2007-11-06 18:03 ronghao 阅读(6563) 评论(7)  编辑  收藏 所属分类: 工作日志


    FeedBack:
    # re: 使用solr搭建你的全文检索
    2008-01-14 14:09 | marten
    2008-1-14 14:02:16 org.apache.catalina.core.AprLifecycleListener init
    信息: The Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jdk1.6.0_02\bin;D:\Tomcat 6.0\bin
    2008-1-14 14:02:16 org.apache.coyote.http11.Http11Protocol init
    信息: Initializing Coyote HTTP/1.1 on http-8080
    2008-1-14 14:02:16 org.apache.catalina.startup.Catalina load
    信息: Initialization processed in 907 ms
    2008-1-14 14:02:17 org.apache.catalina.core.StandardService start
    信息: Starting service Catalina
    2008-1-14 14:02:17 org.apache.catalina.core.StandardEngine start
    信息: Starting Servlet Engine: Apache Tomcat/6.0.13
    2008-1-14 14:02:17 org.apache.catalina.startup.HostConfig deployWAR
    信息: Deploying web application archive apache-solr-1.2.0.war
    2008-1-14 14:02:17 org.apache.solr.servlet.SolrDispatchFilter init
    信息: SolrDispatchFilter.init()
    2008-1-14 14:02:17 org.apache.solr.core.Config getInstanceDir
    信息: No /solr/home in JNDI
    2008-1-14 14:02:17 org.apache.solr.core.Config getInstanceDir
    信息: Solr home defaulted to 'null' (could not find system property or JNDI)
    2008-1-14 14:02:17 org.apache.solr.core.Config setInstanceDir
    信息: Solr home set to 'solr/'
    2008-1-14 14:02:17 org.apache.catalina.core.StandardContext filterStart
    严重: Exception starting filter SolrRequestFilter
    java.lang.NoClassDefFoundError: Could not initialize class org.apache.solr.core.SolrConfig
    at org.apache.solr.servlet.SolrDispatchFilter.init(SolrDispatchFilter.java:74)
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:275)
    at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:397)
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:108)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:3693)
    at org.apache.catalina.core.StandardContext.start(StandardContext.java:4340)
    at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:791)
    at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:771)
    at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:525)
    at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:825)
    at org.apache.catalina.startup.HostConfig.deployWARs(HostConfig.java:714)
    at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:490)
    at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1138)
    at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:311)
    at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSupport.java:117)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1053)
    at org.apache.catalina.core.StandardHost.start(StandardHost.java:719)
    at org.apache.catalina.core.ContainerBase.start(ContainerBase.java:1045)
    at org.apache.catalina.core.StandardEngine.start(StandardEngine.java:443)
    at org.apache.catalina.core.StandardService.start(StandardService.java:516)
    at org.apache.catalina.core.StandardServer.start(StandardServer.java:710)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:566)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413)
    2008-1-14 14:02:17 org.apache.catalina.core.StandardContext start
    严重: Error filterStart
    2008-1-14 14:02:17 org.apache.catalina.core.StandardContext start
    严重: Context [/apache-solr-1.2.0] startup failed due to previous errors
    2008-1-14 14:02:18 org.apache.coyote.http11.Http11Protocol start
    信息: Starting Coyote HTTP/1.1 on http-8080
    2008-1-14 14:02:18 org.apache.jk.common.ChannelSocket init
    信息: JK: ajp13 listening on /0.0.0.0:8009
    2008-1-14 14:02:18 org.apache.jk.server.JkMain start
    信息: Jk running ID=0 time=0/50 config=null
    2008-1-14 14:02:18 org.apache.catalina.startup.Catalina start
    信息: Server startup in 1895 ms
    这个是什么原因造成的呢?我一启动就报这个错,苦恼中。。。  回复  更多评论
      
    # re: 使用solr搭建你的全文检索
    2008-02-13 15:01 | jinglepot
    應該是你的Tomcat有問題, 找不到Tomcat的liberary, Tomcat 沒裝好.  回复  更多评论
      
    # re: 使用solr搭建你的全文检索
    2008-03-02 18:58 | 認真讀
    你好,我拜讀你的文章,並很有助益我建置完成solr

    但我在進行庖丁分詞,的部分時,只要我把
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    換成我按照,你的方法改的class後就會出現說我找不到
    org/apache/lucene/analysis/TokenStream

    因為我使用預設的WhitespaceTokenizerFactory就不會有問題,所以請問版主,這是什麼問題呢



    資訊: created text_ws: org.apache.solr.schema.TextField
    2008/3/2 下午 06:55:35 org.apache.solr.servlet.SolrDispatchFilter init
    嚴重的: Could not start SOLR. Check solr/home property
    java.lang.NoClassDefFoundError: org/apache/lucene/analysis/TokenStream
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
    at java.security.SecureClassLoader.defineClass(SecureClassLoade
    4)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:260)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:56)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:195)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:299)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276
    at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(Webap
    der.java:1273)
    at org.apache.catalina.loader.WebappClassLoader.loadClass(Webap
    der.java:1204)
    at ...................  回复  更多评论
      
    # re: 使用solr搭建你的全文检索
    2008-03-04 14:51 | 木哥哥
    我在配置过程中发现一个问题,

    当搜索关键字中间没有空格分开的时候,比如“漫画游戏”,虽然分词能分出来,但是查询的时候却不能自动组合成和“漫画 游戏”一样的查询字符串,查询出来的结果也完全不一样,甚至没有结果。

    “漫画游戏”的调试信息
    - <lst name="debug">
    <str name="rawquerystring">漫画游戏</str>
    <str name="querystring">漫画游戏</str>
    <str name="parsedquery">PhraseQuery(all:"漫画 游戏")</str>
    <str name="parsedquery_toString">all:"漫画 游戏"</str>
    <lst name="explain" />
    </lst>
    “漫画 游戏”的调试信息
    <str name="rawquerystring">漫画 游戏</str>
    <str name="querystring">漫画 游戏</str>
    <str name="parsedquery">all:漫画 all:游戏</str>
    <str name="parsedquery_toString">all:漫画 all:游戏</str>
    - <lst name="explain">
    <str name="id=http://www.caihongtang.com/kind1/game4289.htm,internal_docid=34">1.1388016 = (MATCH) sum of: 0.6806047 = (MATCH) weight(all:漫画 in 34), product of: 0.7730782 = queryWeight(all:漫画), product of: 2.8458266 = idf(docFreq=5) 0.2716533 = queryNorm 0.8803827 = (MATCH) fieldWeight(all:漫画 in 34), product of: 1.4142135 = tf(termFreq(all:漫画)=2) 2.8458266 = idf(docFreq=5) 0.21875 = fieldNorm(field=all, doc=34) 0.4581969 = (MATCH) weight(all:游戏 in 34), product of: 0.6343107 = queryWeight(all:游戏), product of: 2.335001 = idf(docFreq=9) 0.2716533 = queryNorm 0.72235405 = (MATCH) fieldWeight(all:游戏 in 34), product of: 1.4142135 = tf(termFreq(all:游戏)=2) 2.335001 = idf(docFreq=9) 0.21875 = fieldNorm(field=all, doc=34)</str>
    <str name="id=http://www.caihongtang.com/kind1/game1111.htm,internal_docid=36">1.1388016 = (MATCH) sum of: 0.6806047 = (MATCH) weight(all:漫画 in 36), product of: 0.7730782 = queryWeight(all:漫画), product of: 2.8458266 = idf(docFreq=5) 0.2716533 = queryNorm 0.8803827 = (MATCH) fieldWeight(all:漫画 in 36), product of: 1.4142135 = tf(termFreq(all:漫画)=2) 2.8458266 = idf(docFreq=5) 0.21875 = fieldNorm(field=all, doc=36) 0.4581969 = (MATCH) weight(all:游戏 in 36), product of: 0.6343107 = queryWeight(all:游戏), product of: 2.335001 = idf(docFreq=9) 0.2716533 = queryNorm 0.72235405 = (MATCH) fieldWeight(all:游戏 in 36), product of: 1.4142135 = tf(termFreq(all:游戏)=2) 2.335001 = idf(docFreq=9) 0.21875 = fieldNorm(field=all, doc=36)</str>
    <str name="id=http://www.caihongtang.com/kind1/game4269.htm,internal_docid=35">0.2314244 = (MATCH) product of: 0.4628488 = (MATCH) sum of: 0.4628488 = (MATCH) weight(all:游戏 in 35), product of: 0.6343107 = queryWeight(all:游戏), product of: 2.335001 = idf(docFreq=9) 0.2716533 = queryNorm 0.7296878 = (MATCH) fieldWeight(all:游戏 in 35), product of: 1.0 = tf(termFreq(all:游戏)=1) 2.335001 = idf(docFreq=9) 0.3125 = fieldNorm(field=all, doc=35) 0.5 = coord(1/2)</str>
    <str name="id=http://www.caihongtang.com/kind1/game2222.htm,internal_docid=37">0.2314244 = (MATCH) product of: 0.4628488 = (MATCH) sum of: 0.4628488 = (MATCH) weight(all:游戏 in 37), product of: 0.6343107 = queryWeight(all:游戏), product of: 2.335001 = idf(docFreq=9) 0.2716533 = queryNorm 0.7296878 = (MATCH) fieldWeight(all:游戏 in 37), product of: 1.0 = tf(termFreq(all:游戏)=1) 2.335001 = idf(docFreq=9) 0.3125 = fieldNorm(field=all, doc=37) 0.5 = coord(1/2)</str>
    </lst>

    我的MSN:xugp@live.com  回复  更多评论
      
    # re: 使用solr搭建你的全文检索
    2008-12-30 13:36 | leegene
    我和楼上的“木哥哥”遇到的问题一样,查询“诺基亚手机”,分词已经成功,但查询结果不对。楼主有没有解决方案?  回复  更多评论
      
    # re: 使用solr搭建你的全文检索
    2009-05-04 20:50 | 观云
    好贴,赞一个,。。  回复  更多评论
      
    # re: 使用solr搭建你的全文检索
    2009-09-03 08:19 | 聚资库
    好东西,学习中...  回复  更多评论
      
  • 相关阅读:
    Spring boot unable to determine jdbc url from datasouce
    Unable to create initial connections of pool. spring boot mysql
    spring boot MySQL Public Key Retrieval is not allowed
    spring boot no identifier specified for entity
    Establishing SSL connection without server's identity verification is not recommended
    eclipse unable to start within 45 seconds
    Oracle 数据库,远程访问 ora-12541:TNS:无监听程序
    macOS 下安装tomcat
    在macOS 上添加 JAVA_HOME 环境变量
    Maven2: Missing artifact but jars are in place
  • 原文地址:https://www.cnblogs.com/cy163/p/1567995.html
Copyright © 2011-2022 走看看