我在我的一个项目中使用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以及是否存在更改问题?我无法找到任何文件。
答案 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。