Lucene SimpleFacetedSearch Facet计数超过2048

时间:2012-03-01 18:05:02

标签: lucene lucene.net

我在我的一个项目中使用Lucene.net偶然发现了一个问题,我使用SimpleFacetedSearch功能进行分面搜索。

我抛出异常

  

分面数超过2048

我添加了另一个方面时,我正在面对3个列,我得到了例外。

如果我删除了所有其他方面,则新方面可以正常工作。

深入研究SimpleFacetedSearch的源代码我可以在SimpleFacetedSearch的构造函数中看到它检查的facet数量不超过MAX_FACETS,这是一个设置为2048的常量。

  foreach (string field in groupByFields)
  {
    ...
    num *= fieldValuesBitSets1.FieldValueBitSetPair.Count;
    if (num > SimpleFacetedSearch.MAX_FACETS)
        throw new Exception("Facet count exceeded " + (object) SimpleFacetedSearch.MAX_FACETS);
    fieldValuesBitSets.Add(fieldValuesBitSets1);
    ...
  }

然而,由于它是公开的,我可以像这样设置它。

SimpleFacetedSearch.MAX_FACETS = int.MaxValue;

有谁知道为什么设置为2048以及是否存在更改问题?我无法找到任何文件。

2 个答案:

答案 0 :(得分:2)

在更改它时不应该有任何问题。但请记住,当搜索结果很大但是小平面计数不超过某些数字时,使用Bitsets(由内部SimpleFacetedSearch完成)会更高效。 (假设1000个方面10M命中)

如果您有更多方面但搜索结果不是很大,您可以迭代结果(在收集器中)并创建方面。这样您可以获得更好的性能。 (说100K切面1000次点击)

因此,2048可能是一个优化数字,超过它可能会导致性能下降。

答案 1 :(得分:1)

MAX_FACETS要避免的问题是内存使用和性能之一。 在内部,SimpleFS使用位图来记录每个facet值使用的文档。每个文档都有一个位,每个值都有一个单独的位图。因此,如果您有很多值,所需的内存量会快速增长,特别是如果您还有大量文档。 memory = values * documents / 8 bytes。

我的公司拥有包含数百万个文档和数十万个值的索引,这些索引需要很多GB的内存。

我创建了另一个我称为SparseFacetedSearcher的实现。这会记录每个值的文档ID。因此,您只需为每个文档支付点击费用。如果每个文档中只有一个值(如产品类别),那么收支平衡点是指您有超过32个值(超过32个产品类别)。 在我们的例子中,内存使用量已降至几百MB。

随时查看https://github.com/Artesian/SparseFacetedSearch