我正在使用Hibernate Search / Lucene来维护一个非常简单的索引,以便按名称查找对象--没有什么花哨的东西。
我的模型类都扩展了一个类NamedModel,基本上如下所示:
@MappedSuperclass
public abstract class NamedModel {
@Column(unique = true)
@Field(store = Store.YES, index = Index.UN_TOKENIZED)
protected String name;
}我的问题是,在查询名称以特定字母开头的对象的索引时,我得到了一个BooleanQuery$TooManyClauses异常。像"name:lin*"这样的查询将不会出现问题,事实上,任何在通配符之前使用多个字母的查询都可以。
当我在网上搜索类似的问题时,我只发现人们使用相当复杂的查询,这似乎总是导致异常。我不想增加maxClauseCount,因为我不认为仅仅因为达到了限制就改变限制是一种好的做法。
这里有什么问题?
发布于 2009-10-15 08:39:28
Lucene试图将您的查询从简单的name:l*重写为所有术语都以l开头的查询(类似于name:lou OR name:la OR name: ...) -我相信这是为了更快。
作为解决方法,您可以使用ConstantScorePrefixQuery而不是PrefixQuery
// instead of new PrefixQuery(prefix)
new ConstantScoreQuery(new PrefixFilter(prefix));然而,这改变了文档的评分(因此,如果您依赖评分进行排序,则排序)。当我们面临需要score (和boost)的挑战时,我们决定寻找一个解决方案,如果可能的话,我们使用PrefixQuery,并在需要的地方后退到ConstantScorePrefixQuery:
new PrefixQuery(prefix) {
public Query rewrite(final IndexReader reader) throws IOException {
try {
return super.rewrite(reader);
} catch (final TooManyClauses e) {
log.debug("falling back to ConstantScoreQuery for prefix " + prefix + " (" + e + ")");
final Query q = new ConstantScoreQuery(new PrefixFilter(prefix));
q.setBoost(getBoost());
return q;
}
}
};(作为增强,可以使用某种类型的LRUMap来缓存以前失败的术语,以避免再次进行代价高昂的重写)
不过,我不能帮助你将其集成到Hibernate搜索中。切换到Compass后,您可能会问;)
https://stackoverflow.com/questions/1570911
复制相似问题