Lucene / Solr如何在多场/分面搜索中实现高性能?

时间:2011-04-05 13:49:40

标签: lucene internals faceted-search

上下文

这是一个主要关于Lucene(或可能是Solr)内部的问题。主题是分面搜索,其中搜索可以沿着对象的多个独立维度(方面)发生(例如,汽车的大小,速度,价格)。

当使用关系数据库实现时,对于大量方面,多字段索引没有用,因为可以按任何顺序搜索构面,因此使用特定有序多索引的可能性很小,并创建所有可能的排序指数是无法忍受的。

Solr被广告以应对分面搜索任务,如果我认为正确必须与Lucene(据称)在多字段查询(其中文档的字段与对象的构面相关)上表现良好。

问题

Lucene的反向索引可以存储在关系数据库中,并且使用单字段索引也可以通过RDBMS轻松实现匹配文档的交叉。

因此,Lucene应该有一些先进的多字段查询技术,而不仅仅是根据倒排索引获取匹配文档的交集。

所以问题是,这种技巧/技巧是什么?更广泛地说:为什么Lucene / Solr在理论上可以实现比RDBMS更好的分面搜索性能(如果是这样)?

注意:我的第一个猜测是,Lucene会使用一些空间分区方法将从文档字段构建的向量空间划分为维度,但据我所知,Lucene并非纯粹基于向量空间。

2 个答案:

答案 0 :(得分:6)

<强>车花

刻面有两个答案,因为刻面有两种类型。我不确定其中任何一个都比RDBMS快。

  1. Enum faceting。查询结果是位向量,如果第i个文档是匹配,则第i位为1。 facet也是一个位向量,因此交集只是一个按位AND。我不认为这是一种新颖的方法,大多数RDBMS可能都支持它。
  2. 字段缓存。这只是一个正常(非倒置)索引。这里运行的SQL样式查询如下:

    从field_cache中选择facet,count(*) 其中docId在query_results中 group by facet

  3. 同样,我不认为这是普通RDBMS无法做到的事情。索引是跳过列表,以docId为键。

    多期搜索

    这是Lucene闪耀的地方。为什么Lucene的方法如此之好太长而无法在此发布,但我可以推荐this post on Lucene Performance或其中的相关论文。

答案 1 :(得分:3)

可以在http://yonik.wordpress.com/2008/11/25/solr-faceted-search-performance-improvements/

找到解释性帖子
  

新方法的工作原理是将索引字段取消反转,以便快速查找任何给定文档的字段中的术语。它实际上是一种混合方法 - 为了节省内存和提高速度,许多文档中出现的术语(超过5%)不是不反转的,而是使用传统的集合交叉逻辑来获取计数。