solr 通过【配置、多值字段、动态字段】来解决文本表达式查询精确到句子的问题20171214

一、Solr Multivalue field属性positionIncrementGap理解

分类:Lucene

2014-01-22 10:39阅读(3596)评论(0)

参考:http://rockiee281.blog.163.com/blog/static/19385222920127225619919/

Solr里头可以设计Field为Multivalue类型,这样的一个好处是可以很方便的设置copyField,在我们的项目中也有使用。

但是一直以来都有一个问题困扰着我,就是对multivalue里头多个值域的搜索问题。多个value之间我认为应该是保持相互独立的,但是在实际搜索中感觉solr把所有的值域都串在一起,当作一个长value来处理,没有达到我想要的效果。后来通过搜索,我发现solr的field type中有一个positionIncrementGap字段,

,在网上看到一段讨论:http://lucene.472066.n3.nabble.com/positionIncrementGap-in-schema-xml-td488338.html。其中有人举了一个例子:

一看之下大喜过望,这不是就是我想要的效果么 马上去翻我solr的schema.xml的配置,一看我就凉了:

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

<analyzer type="query">

<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="dic">

</tokenizer>

<filter class="solr.SynonymFilterFactory" synonyms="synonyms_filter.txt" ignoreCase="true" expand="false"/>

<filter class="solr.StandardFilterFactory"/>

</analyzer>

<analyzer type="index">

<tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="dic">

</tokenizer>

<filter class="solr.SynonymFilterFactory" synonyms="synonyms_filter.txt" ignoreCase="true" expand="false"/>

<filter class="solr.StandardFilterFactory"/>

</analyzer>

</fieldtype>

居然之前已经配置过了!!!那就是这个配置没有生效,是什么造成的呢?因为我没有使用solr自己的standardTokenizerFactory,而是为了中文分词使用了MMSeg4J的类,我就把怀疑的目光放到了MMSeg4J身上。检查了MMSegTokenizerFactory的源代码,发现里头木有对positionIncrementGap的处理,以为问题出在这里,但是在深入对比MMSegTokenizerFactory和StandardTokenizerFactory及相关的代码类之后,感觉问题不应该出在建立索引的环节。

之后就是搜了一堆的资料,了解了positionIncrementGap这个字段的含义,其作用就是在对Multivalue Field进行处理的时候,给两个field中相隔的词人为的插入一段固定的distance,然后在使用Lucene/Solr做Phrase query的时候,如果没有指定Slop(对slop的介绍,可以参考:http://blog.csdn.net/rick_123/article/details/6708527),会默认Slop为0,即查询的短语之间应该紧紧挨着,这样对很多情况下都得不到用户想要的结果。解决的办法就是使用phrase query,同时设置一个适当的Slop值,然后为了不让lucene的搜索跨越多个Field Value,设置一个远大于slop的positionIncrementGap,就可以达到目标。在这里不用担心positionIncrementGap设置过大会影响效率,尽情的设吧……

既然了解positionIncrementGap的含义,问题就一目了然,楼主为了查询的方便,使用自定的QueryParser替换了Solr自己默认的,将Phrase search改为了BooleanSearch,所以实际上导致了positionIncrementGap的失效。解决办法就是将BooleanSearch改为MultiPhraseQuery,同时调用MultiPhraseQuery.setSlop(int slop)方法设置slop为50(经验值,根据索引的数据设定,只要远小于positionIncrementGap即可)。测试ok达到效果!

二、多值字段
针对多值字段,查询表达式仍然会被拆分为一个一个的关键词,然后去跨句子去匹配。

三、动态字段
针对动态字段,查询表达式可以精确查到句子,但是不能确保通配查询。

时间: 2024-10-29 19:07:36

solr 通过【配置、多值字段、动态字段】来解决文本表达式查询精确到句子的问题20171214的相关文章

动态字段

转载 http://www.cnblogs.com/skyblog/p/4122571.html 大部分应用都不需要自动创建表单创建字段的功能,但使用少部分的动态字段还是可以减少不少麻烦.比如电子商务里面的商品,有很多种商品,每种商品按说都需要定义一张表,但那行不通,因为太多了不说,商品种类还是动态增加的,总不能增加一个商品就增加一张表.类似的情况很多,特别是对于现实中有派生关系的对象组,比如奖励,奖励又分很多种,我们也不需要为每一种奖励定义一张表. 使用动态字段可以解决这种情况,一般来说有两种

SQL Server 动态行转列(参数化表名、分组列、行转列字段、字段

一.本文所涉及的内容(Contents) 本文所涉及的内容(Contents) 背景(Contexts) 实现代码(SQL Codes) 方法一:使用拼接SQL,静态列字段: 方法二:使用拼接SQL,动态列字段: 方法三:使用PIVOT关系运算符,静态列字段: 方法四:使用PIVOT关系运算符,动态列字段: 扩展阅读一:参数化表名.分组列.行转列字段.字段值: 扩展阅读二:在前面的基础上加入条件过滤: 参考文献(References) 二.背景(Contexts) 其实行转列并不是一个什么新鲜的

ADF Faces 表格应用基础案例二:动态字段+事件处理【附样例工程】

本文提供一个基于ADF Face组件开发样例工程,实现表格开发中常见的处理: 1.Map对象+Bean对象填充表格的数据行. 2.使用静态列.动态列.嵌套列的实现方法. 3.介绍表格中表单组件的使用方法. 4.介绍表格单行选中事件的处理过程. 本文是基于"ADF Faces 表格应用基础案例一:应用List<Class>填充文本表格"编写的,会省去许多细节部分的介绍. 实现的基本思路: 将样例工程的创建过程分为几个小的阶段,每个阶段实现了不同的目标. 第一阶段: 表格数据:

1.4.5 动态字段

动态字段允许solr索引没有在schema.xml中明确定义的字段,通过提供一个灵活的添加文档的机制,可以使你的应用不会那么脆弱. <dynamicField name="*_i" type="int" indexed="true" stored="true"/> 相关主题 SchemaXML-Dynamic Field

mybatis操作动态表+动态字段+存储过程

存储过程 statementType="CALLABLE" <!-- 计算金额存储过程--> <update id="getCalcDistributorSettle" statementType="CALLABLE" parameterType="java.util.Map"> <![CDATA[ CALL procCalcDistributorSettle (#{ID},#{message})

c#,win frm 水晶报表,动态字段

动态字段做之前怎么也做不出来,愁死. 后来发现其实挺简单,似乎只要是多个重复字段的数据,就可以自动排出来,只要把他们放在section3(详细资料): c0到c14是将要重复输出的字段(数据不重复,如List<CCC>,CCC含有c0到c14这些属性).然后将  section3(详细资料)  的高度压紧,因为重复的时候,行高就是section3的高度,不压紧将会留白. 这样,就可以动态字段了,虽然还是有点局限的感觉 然后我就发现,我有一张图片(已转byte[])没有办法放进去了,直接放进CC

mybatis 操作动态表+动态字段+存储过程

mybatis 操作动态表+动态字段+存储过程 存储过程   statementType="CALLABLE" <!-- 计算金额存储过程--> <update id="getCalcDistributorSettle" statementType="CALLABLE" parameterType="java.util.Map"> <![CDATA[ CALL procCalcDistributo

使用Python创建MySQL数据库实现字段动态增加以及动态的插入数据

应用场景: 我们需要设计一个数据库来保存多个文档中每个文档的关键字.假如我们每个文档字符都超过了1000,取其中出现频率最大的为我们的关键字. 假设每个文档的关键字都超过了300,每一个文件的0-299号存储的是我们的关键字.那我们要建这样一个数据库,手动输入这样的一个表是不现实的,我们只有通过程序来帮我实现这个重复枯燥的操作. 具体的示意图如下所示: 首先图1是我们的原始表格: 图1 这个时候我们需要程序来帮我们完成自动字段的创建和数据的插入. 图2 上图是我们整个表的概况.下面我们就用程序来

EasyUI DataGrid根据字段动态合并单元格

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="fn" uri=&