Solr配置文件分析与验证

2019-03-27 00:24|来源: 网路

前面一篇开始学习solr的时候,做了个入门的示例http://6738767.blog.51cto.com/6728767/1401865。虽然可以检索出内容,但总和想象的结果有差异――比如,检索“天龙”两个字,按常规理解,就应该只出来《天龙八部》才对,可是竟然也会把《倚天屠龙记》检出来。后来研究了一下,发现系统是这样处理的:无论是抽索引时还是分析检索词时,都把所有文字按单字拆开。这样,刚好《倚天屠龙记》里包含“天”和“龙”。于是对照solr的配置文件schema.xml做了一些分析和验证。下面来看一下:

schema.xml里,对检索结果有最直接影响的有这么几项:

<solrQueryParserdefaultOperator="OR"/>

这一行在文件较靠后的位置,但我最先拿出来说。这表示,对拆分后的检索词是按照“且”还是“或”的关系选定结果。默认是OR,可以改成AND。象前面例子,如果再有一本《天天向上》,也一样会被检索出来。因为包含了“天”字。那就差的更远了。所以如果采用这个默认的单字拆分法,那最好是用AND,否则结果就太乱了。

好了,假定我们改成了AND,那么结果是《天天向上》没有了,但《倚天屠龙记》还在的。因为既有“天”又有“龙”,说明单字拆分法有不足之处。

决定这个单字拆分法的是谁呢?仔细检查文件,我们发现这一行:

<field name="name"type=" text_general" indexed="true"stored="true"/>

表示name这个字段是text_general类型的。这就靠谱了,多半text_general类型的处理方式就是单字拆分。

有没有更好的分词方法呢,当然有,而且肯定不止一种。我按照网上的例子采用了mmseg4j。使用方法很简单,把解压后的几个jar文件放到classpath目录下。然后在schema.xml里增加下面几行:

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

<analyzer>

<tokenizerclass="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory"mode="complex" dicPath="./dic"/>

<filter class="solr.LowerCaseFilterFactory"/>

</analyzer>

 </fieldType>

 <fieldTypename="textMaxWord" class="solr.TextField"positionIncrementGap="100" >

      <analyzer>

            <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory"mode="max-word" dicPath="./dic"/>

            <filterclass="solr.LowerCaseFilterFactory"/>

      </analyzer>

</fieldType>

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

<analyzer>

<tokenizerclass="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory"mode="simple" dicPath="./dic"/>

            <filterclass="solr.LowerCaseFilterFactory"/>

      </analyzer>

</fieldType>

这里定义了三种fieldType,分别是textComplextextMaxWordtextSimple。名称无所谓,重要的是子元素定义了分词器和过滤器使用的类:com.chenlb.mmseg4j.solr.MMSegTokenizerFactorysolr.LowerCaseFilterFactory。其实三种用的类是相同的,只是后面有个mode不同。

这里只是定义了分词类型,我们要把这个分词类型应用到我们的数据里才行。所以,要把<field name="name" type="textSimple"indexed="true" stored="true"/> ――我这里改成了textSimple 。在fieldTypefieldname的共同作用下,我们终于可以完成中文习惯上的分词了。当然要重新运行代码,重新抽索引才行,而且字段name里得有东西(参考上一篇的代码)。

搜索“name:天龙”,结果为空。这又是怎么回事呢?难道又错了?其实如果想看分词效果,solr的管理端有个分析工具很好用。

 wKioL1N9oHXx59JUAADXM6YbH7E552.jpg

进到分析页面,上面输入字段名称name,下面输入文本,看一下它倒底是怎么分的

 wKioL1N9oMqSHnPgAAGjHe34x7Q176.jpg

原来textSimple方式把“天龙八部”作为一个整词了,难怪我们搜“天龙”没结果,再搜“天龙八部”,有结果了。晕,这也太不符合习惯了。少字没结果,多字反倒有结果。接着,我们再换一种试试:

<field name="name" type="textMaxWord"indexed="true" stored="true"/> name字段用textMaxWord类型,这表示采用最大化分词的方式。再来分析一下:

wKiom1N9oQmzfiTGAADCOXceszg187.jpg

这回差不多了,“天龙八部”被分成“天龙”“八”“部”三个词。搜索这三个词都有结果了,而且是唯一结果。

 

换个搜索写法:

不写name:天龙,直接写天龙。晕死,倚天屠龙记又出来了。接着看schema.xml

<defaultSearchField>text</defaultSearchField>

这表示默认搜索字段,如果前面什么都不写,就到text里去查找。而text怎么定义的呢?再找:

<field name="text" type="text_general"indexed="true" stored="false"multiValued="true"/>

果然,又回到text_general来了,还是单字拆分法。

等等,回忆一下,我们并没有text这个字段啊(参考上一篇代码),我们只录入了三个字段idnameprice,这个text是谁?继续找,在这里――

<copyField source="cat"dest="text"/>

<copyField source="name"dest="text"/>

<copyField source="manu"dest="text"/>

<copyField source="features"dest="text"/>

<copyField source="includes"dest="text"/>

这几行表示,把catnamemanufeaturesincludes都作为text看待(一般是为提供通用检索或简单检索功能用的),texttext_general类型的,还是默认的。所以不写条件时当然又回到单字查找法了。

 

总结一下:

5个元素交互作用,最终共同影响着搜索结果。

fieldType定义了可选的类型,当然定义了未必就用

field定义了某个字段具体是什么fieldType

copyField提供了一个同时查找多个字段的简便方法

defaultSearchField定义了不写字段条件时的查找范围

solrQueryParser defaultOperator定义了各分词之间采用什么逻辑组合


本文出自 “空空如也” 博客,请务必保留此出处http://6738767.blog.51cto.com/6728767/1415319


转自:http://6738767.blog.51cto.com/6728767/1415319

相关问答

更多
  • 在springboot配置sqlserver文件步骤如下: 1、打开项目配置文件 application.properties。 2、这里推荐一个新的写项目属性配置文件的:application.yml。优点在于它不用重复写代码。 3、这二者选一即可,因而我用了application.yml就把application.properties删除了。 4、特别注意语法:每个冒号后面是有空格的。当然这里eclipse也通过颜色对这个语法进行了提示。 5、特别注意语法:每个冒号后面是有空格的。当然这里eclipse ...
  • Windows版的Redis有2个配置文件,一个是:redis.windows.conf,另一个是redis.windows-service.conf。
  • 从5.0开始,solr采用了自动发现模式(discovery,区别于传统模式legacy),Solr会自动找到安装目录中、或solr_home中的配置文件:core.properties,并根据里面的name属性来初始化相对于的core。solr.xml中仍然会定义一些配置参数,但是core本身不会定义在这个文件中。 Solr会递归搜索所有solr和solr_home目录和子目录,当在一个目录中发现core.properties后,就停止搜索当前目录的所有子目录,转向下一个同级目录搜索。所以,下面两个配置只 ...
  • 配置步骤如下: 1、下载tomcat、solr、并解压它们 2、将solr.war拷贝至tomcat/webapps下面 3、将solr/example下面的multicore拷贝至tomcat下面,并改名为solr 4将solr/solr.xml中的 改为了 5、cd tomcat;bin/startup.sh启动tomcat 6、首先要保证已经将solr/solr.xml中的 改为了 7、在运行的时候将core1复制一份,改名为 core2 8、之后发送请求 http:// localhost:8080 ...
  • solr的三个配置文件: 1、solrconfig.xml 只配置一次就够了 2、data-config.xml 配置数据库与solr搜索的映射关系,需要按实际情况处理 3、schema.xml 配置solr搜索字段
  • Solr5 +我们可以使用configSets使用通用配置文件 可以在configsets目录中一次定义公共配置文件。 例如:/ solr / configsets / my_configs / conf /和core.property用于单个核心,如下所示: 在core1中:name = core1 configSet = my_configs schema = schema_my.xml config = solrconfig_my.xml 在core2中:name = core2 configSet ...
  • 我建议外部化依赖于环境的参数: 1) DIH 您可以使用占位符来获取此信息:例如
  • 我的理解是,当您要求GHC编译代码以进行分析时,代码的二进制接口会发生变化。 (并且它会与RTS的不同版本链接)。由于同一程序中的所有代码都必须具有相同的二进制接口,所以这就是原因。 为了避免这种情况,GHC必须支持在同一个程序中混合不同的二进制接口,或者找到一种方法来使用与非异步代码相同的接口来编译分析代码。 我想这些事情都不是特别微不足道的事情。 虽然我确实认为这很烦人 My understanding is that when you ask GHC to compile code for profi ...
  • 在文档中找到了这个:请参阅以下部分: 使用zkcli上传配置使用zkcli上传配置时使用zkcli或SolrJ 上传配置 您可以执行以下操作来推送文件: zkcli.sh -zkhost localhost:2181 -cmd putfile /solr.xml /path/to/solr.xml 以及上传配置文件的类似内容: ./server/scripts/cloud-scripts/zkcli.sh -zkhost localhost:9983 -cmd upconfig -confname
  • 一个更安全的选项,我建议在您的网络服务器中配置JNDI 。 如何配置JNDI? 本页介绍了如何使用Tomcat执行此操作。 它也可以用于其他流行的网络服务器。 您可以在数据配置文件中使用JNDI名称,如下所示: < dataSource name="xyz" jndiName="jdbc/xyz" type="JdbcDataSource"/> A more secure option, I would suggest is to configure a JNDI in your webserver. H ...