lucene 中的TooManyClause 异常

              使用Lucene检索过程中如果用到RangeQuery,PrefixQuery,WildcardQuery,FuzzyQuery等Query的时候,可能会产生 TooManyClauses异常。为什么呢? 
以 RangeQuery为例,如果日期范围为 19990101到 20091231,在索引文件中有 19990102,19990103等等这些日期词组,那么RangeQuery 会被扩展成“19990102 OR 19990103”,成了2 个子句。可以想象,如果索引文件里面在这个时间段内的日期有很多,那么就会产生很多子句。 PrefixQuery 等也是同样的道理,如查询词为“法*”,如果索引文件中有“法律”、“法场”、“法医”、“法典”等等,这个 Query就会被扩展成“法律 OR  法场 OR  法医 OR  法典”,或许会更多更多。 而为了节省内存,Lucene 默认将子句数目限制为 1024,如果超出限制,就会抛出TooManyClauses异常。  怎么解决这个问题呢,Lucene提供了三种方法: 

(1)  使用 filter 替代 Query,当然这是以牺牲查询速度为代价的,不过可以通过缓存的方式缓解这个问题。仍然以前面 RangeQuery 为例,可以使用RangeFilter来替代 RangeQuery,如下:   

之前的代码: 
BooleanQuery simpleQuery = new BooleanQuery(); 
Term dateLower = new Term("publishDate", startYear + "0101"); 
Term dateUpper = new Term("publishDate", endYear + "1231"); 
RangeQuery dateQuery = new RangeQuery(dateLower, dateUpper, true); 
simpleQuery.add(dateQuery, Occur.MUST); 
之后的代码: 
BooleanQuery simpleQuery = new BooleanQuery(); 
RangeFilter dateFilter = new RangeFilter("publishDate", startYear + "0101", endYear + "1231", 
true, true); 
FilteredQuery filteredQuery = new FilteredQuery(simpleQuery, dateFilter); 518 

 (2)  通过 BooleanQuery.setMaxClauseCount(10240)来限制数目。这样会加大内存的消耗。使用 BooleanQuery.setMaxClauseCount(Integer.MAX_VALUE),可以完全去掉这个限制。 

(3)  对于范围查询,可以尽可能的降低精度,比如如果查询不需要精确到月份与日期,只需

要精确到年,据说可以使用 DateTools这个类可以很简单解决时间转化问题。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值