Solr的TrieField范围查询分析

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

solr从1.4版本开始,提供了一种字段类型TrieField(TrieLongField、TrieIntField等),用于范围查询,性能比普通的数值类型要快10倍。为什么会快那么多呢?网上找不到相关资料,通过分析源代码,大概了解了其原理,给大家分享下。

  • TrieField字段配置

<fieldTypename=”tint”precisionStep=”8″omitNorms=”true”positionIncrementGap=”0″/>

其中precisionStep代表字段值分段保存的时候,截断精度的大小。一般来说,其值越小,索引大小越大,查找速度越快。

  • TrieField索引

TrieField字段在lucene中是用多个field来保存的,field的多少根据precisionStep决定,比如TrieIntField,precisionStep=”8″,则保存到索引中就是4个field,如图,32位的Int,每次缩进8位保存为一个field,新的field采用char数组来保存。因此索引的大小会比普通的IntField大。

  • TrieField的范围查询:

TrieField的范围查询通过高位范围匹配,低位边缘匹配,得到需要查询的term,再查询这些term得到docid来实现。

查找的过程:

1、将查找的范围A~B的上下界A、B值,取出最高8位,标记为A1、B1,到第一段找在(A1~B1)内的term,得到需要查找的termlist1

2、继续取A、B值的最高16位,标记为A2、B2,到第二段来查在(A2~A111111111]和[B111111111,B2)范围内的Term,得到termlist2

3、继续取A、B值的最高24位,标记为A3、B3,到第三段来查在(A3~A211111111]和[B211111111,B3)范围内的Term,得到termlist3

4、继续取A、B值的最高24位,也即A、B值,到第四段来查找[A~A311111111]和[B311111111,B]范围内的Term,得到termlist4

5、最后查询这些term,归并,就得到了符合查询条件的docid了。从上面的描述,我们可以看到,需要查询的term最多为254+255*2+255*2+256*2=1786个,传统的方式A~B个term要小的多,因此性能有很大的提升。


转自:http://aliapp.blog.51cto.com/8192229/1325947

相关问答

更多
  • public static Map<String, Integer> queryByGroup(String qStr,String groupField,String sortField,boolean asc,Integer pageSize,Integer pageNum){ Map<String, Integer> rmap = new LinkedHashMap<String, Integer>(); try { SolrServer server = getS ...
  • 我不知道为什么这不工作,但这是逻辑上相同的,它的工作: -(myField:superneat AND -myOtherField:somethingElse) 也许这与在查询中定义相同的字段两次有关 尝试在solr-user组中询问,然后在这里发回最后的答案! I don't know why that doesn't work, but this one is logically equivalent and it does work: -(myField:superneat AND -myOther ...
  • 你可以试试WordDelimiterFilterFactory ,它有很多可以尝试的选项...... 您可以为您的字段尝试以下字段类型。
    有条目的十大公司(以及每个公告的通知数量) :面对公司,做一个: -搜索。 如果每个通知都有一个文档,您将在分面请求中获得所需的结果。 每年公布的通知数量 :在日期时间范围内以年份为间隔。 发布通知的最多和最不受欢迎的日/月 :为日期和月份添加两个显式字段,并在这些字段上添加facet。 也许你也可以在工作日编制索引吗? 发布通知当天最受欢迎的小时 :制作一个仅包含小时的字段,其中包含方面。 最长的通知(按字符数) :函数查询是这里的候选者,但是没有strLength函数。 此外,它不适用于您使用文本字段的 ...
  • 您不需要在索引时和查询时进行同义词扩展,只需要其中一个。 想一想,如果你只是在编制索引时这样做,所有列出的单词都将由其所有同义词补充。 然后,当您使用任何这些单词查询索引时,您将匹配所有经历扩展的文档。 没有必要在两端扩展。 并且建议您在索引时执行此操作,因为这样可以加快查询时间。 恕我直言,一般规则应该是尽可能地筹码(包括在查询时扩展同义词几毫秒),以使用户体验更好。 而这些芯片可能会大量堆积。 您可以询问有关我们为何鼓励文档中的数据冗余的相同问题。 You don't need synonym expa ...
  • 首先,我认为Solr通配符比“1或多个”更好地归纳为“0或多个”。 我怀疑这是你问题的根源。 (例如,请参阅WildcardQuery的javadoc 。) 其次,你是否在使用词干,因为我的第一个猜测是你正在处理一个词干问题。 Solr通配符在词干方面可能表现得很奇怪。 这是因为通配符扩展是通过搜索存储在倒排索引中的术语列表来进行的; 这些术语将以词干形式出现(可能类似“gatorad”),而不是来自原始源文本(可能是“gatorade”或“gatorades”)的单词。 例如,假设你有一个词干分析器,把“ ...
  • 说应用通配符查询时不会发生分析是一个很好的规则(我自己已经说了这么多次),但有些错误。 确切的解释是, 任何不是MultiTermAware的标记器或过滤器都将被排除 ,因此Solr试图在没有它们的情况下“做正确的事情”。 您可以在key type="multiterm" (仅使用MultiTermAware组件)下定义自己的分析链,以定义多个查询(例如通配符)的自定义链。 从6.3开始,唯一的多重软件标记器是LowerCaseTokenizer 。 此外,KeywordTokenizer将起作用,因为它会 ...
  • Solr支持在数字范围内搜索数字字段。 它对价格方面很有用。 Numeric Trie以不同的精度水平生成范围边界,因此当您查找适合该范围的条目时,您可以立即拒绝它们的整个组(例如,低于2 ^ 5的任何内容肯定不在范围内)。 Solr support searching numeric fields for numeric ranges. It is useful for things like price facets. Numeric Trie generates the range boundarie ...
  • 所以 - PatternReplaceCharFilter在查询时无法删除破折号,这肯定是奇怪的。 最后,我只是在发送到Solr之前用preg_replace在用户输入的php中进行了一些预查询处理,并且 - 中提琴! - 像预期结果的魅力一样工作。 令人费解的是PatternReplaceCharFilter没有表现...... 这是我用来摆脱破折号的预查询php代码,如果有人需要的话。 $pattern = '/([-])/'; $replacement = ' '; $usrpar = preg_re ...
  • 是的,如果未定义类型,则索引和查询都使用相同的分析器。 Yes, if the type is not defined, the same analyzer is used for both index and query.