发现RangeQuery的问题
edwardpro
2008-05-28
lucene有范围查找,本来想用它做时间段查询的,由于我们的时间段是timestamp所以范围是一个long型的范围,由于timestamp对时间的范围非常大比如一小时就是3600(问题恰恰出在这里),当我改完之后发现执行都会抱booleanquery达到了最大组合数,这个让我百思不得其解,因为我不可能用了那么多,后来看了booleanquery的源码才知道了...
if (clauses.size() == 1) { // optimize 1-clause queries BooleanClause c = (BooleanClause)clauses.get(0); if (!c.isProhibited()) { // just return clause Query query = c.getQuery().rewrite(reader); // rewrite first if (getBoost() != 1.0f) { // incorporate boost if (query == c.getQuery()) // if rewrite was no-op query = (Query)query.clone(); // then clone before boost query.setBoost(getBoost() * query.getBoost()); } return query; } } BooleanQuery clone = null; // recursively rewrite for (int i = 0 ; i < clauses.size(); i++) { BooleanClause c = (BooleanClause)clauses.get(i); Query query = c.getQuery().rewrite(reader); if (query != c.getQuery()) { // clause rewrote: must clone if (clone == null) clone = (BooleanQuery)this.clone(); clone.clauses.set(i, new BooleanClause(query, c.getOccur())); } } if (clone != null) { return clone; // some clauses rewrote } else return this; 具体代码很多,大家有兴趣自己去看,大致的意思这样的,它的range做法是这样:如果是数字那么它就从大到小以+1的方式增加了很多或逻辑的字段,由于我采用了timestamp那么这样必然得到一个很多很多的逻辑组合(一小时就有3600种),因此虽然我不断设大了booleanquery的条件限制数,但依然无法得到满足...而这种方法即使我开很大,那这个效率也是很惊人的低的,所以最后只能把timestamp变成年月日时分秒这样分开算range...由此看来lucene的range有那么一点低能,大家使用时候如果遇到类似问题可以借鉴下. |
|
wifivein
2008-06-02
用RangeFilter就可以,我现在已经完全用它代替RangeQuery了
|
|
edwardpro
2008-06-03
感谢,看了源码果然解决了这个问题
|