You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@lucene.apache.org by Christoph Goller <go...@detego-software.de> on 2003/09/05 14:48:56 UTC

PATCH: RangeQuery

There is a bug in RangeQuery. In case of inclusive == false upperTerm
is chaged in rewrite according to a value from reader.terms(upperTerm).
This means that a RangeQuery has a state that is depending/changing with
search. Thus RangeQueries cannot be reused for several searches.
A JUnit test that demonstrates the problem and a patch that fixes it
are attatched.

Christoph

-- 
*****************************************************************
* Dr. Christoph Goller       Tel.:   +49 89 203 45734           *
* Detego Software GmbH       Mobile: +49 179 1128469            *
* Keuslinstr. 13             Fax.:   +49 721 151516176          *
* 80798 München, Germany     Email:  goller@detego-software.de  *
*****************************************************************

Re: PATCH: RangeQuery

Posted by Otis Gospodnetic <ot...@yahoo.com>.
Christoph,

It looks like this really was a bug in RangeQuery.  Thank you for the
nice unit test and the patch.  I'll commit both to CVS shortly.

Otis

--- Christoph Goller <go...@detego-software.de> wrote:
> There is a bug in RangeQuery. In case of inclusive == false upperTerm
> is chaged in rewrite according to a value from
> reader.terms(upperTerm).
> This means that a RangeQuery has a state that is depending/changing
> with
> search. Thus RangeQueries cannot be reused for several searches.
> A JUnit test that demonstrates the problem and a patch that fixes it
> are attatched.
> 
> Christoph
> 
> -- 
> *****************************************************************
> * Dr. Christoph Goller       Tel.:   +49 89 203 45734           *
> * Detego Software GmbH       Mobile: +49 179 1128469            *
> * Keuslinstr. 13             Fax.:   +49 721 151516176          *
> * 80798 M�nchen, Germany     Email:  goller@detego-software.de  *
> *****************************************************************
> > Index: RangeQuery.java
> ===================================================================
> RCS file:
>
/home/cvspublic/jakarta-lucene/src/java/org/apache/lucene/search/RangeQuery.java,v
> retrieving revision 1.9
> diff -u -r1.9 RangeQuery.java
> --- RangeQuery.java	12 Aug 2003 09:17:53 -0000	1.9
> +++ RangeQuery.java	5 Sep 2003 12:42:19 -0000
> @@ -83,57 +83,57 @@
>          {
>              throw new IllegalArgumentException("Both terms must be
> for the same field");
>          }
> -        this.lowerTerm = lowerTerm;
> +        
> +        // if we have a lowerTerm, start there. otherwise, start at
> beginning
> +        if (lowerTerm != null)
> +            this.lowerTerm = lowerTerm;
> +        else
> +            this.lowerTerm = new Term(upperTerm.field(), "");
> +
>          this.upperTerm = upperTerm;
>          this.inclusive = inclusive;
>      }
>  
>      public Query rewrite(IndexReader reader) throws IOException {
> -      BooleanQuery query = new BooleanQuery();
> -      // if we have a lowerTerm, start there. otherwise, start at
> beginning
> -      if (lowerTerm == null) lowerTerm = new Term(getField(), "");
> -      TermEnum enumerator = reader.terms(lowerTerm);
> -      try {
> -        String lowerText = null;
> -        String field;
> -        boolean checkLower = false;
> -          if (!inclusive) {             // make adjustments to set
> to exclusive
> -            if (lowerTerm != null) {
> -              lowerText = lowerTerm.text();
> -              checkLower = true;
> -            }
> -            if (upperTerm != null) {
> -              // set upperTerm to an actual term in the index
> -              TermEnum uppEnum = reader.terms(upperTerm);
> -              upperTerm = uppEnum.term();
> -            }
> -          }
> -          String testField = getField();
> -          do {
> -            Term term = enumerator.term();
> -            if (term != null && term.field() == testField) {
> -              if (!checkLower || term.text().compareTo(lowerText) >
> 0) {
> -                checkLower = false;
> -                if (upperTerm != null) {
> -                  int compare = upperTerm.compareTo(term);
> -                  /* if beyond the upper term, or is exclusive and
> -                   * this is equal to the upper term, break out */
> -                  if ((compare < 0) || (!inclusive && compare == 0))
> break;
> +
> +        BooleanQuery query = new BooleanQuery();
> +        TermEnum enumerator = reader.terms(lowerTerm);
> +
> +        try {
> +
> +            boolean checkLower = false;
> +            if (!inclusive) // make adjustments to set to exclusive
> +                checkLower = true;
> +
> +            String testField = getField();
> +
> +            do {
> +                Term term = enumerator.term();
> +                if (term != null && term.field() == testField) {
> +                    if (!checkLower ||
> term.text().compareTo(lowerTerm.text()) > 0) {
> +                        checkLower = false;
> +                        if (upperTerm != null) {
> +                            int compare =
> upperTerm.text().compareTo(term.text());
> +                            /* if beyond the upper term, or is
> exclusive and
> +                             * this is equal to the upper term,
> break out */
> +                            if ((compare < 0) || (!inclusive &&
> compare == 0))
> +                                break;
> +                        }
> +                        TermQuery tq = new TermQuery(term); // found
> a match
> +                        tq.setBoost(getBoost()); // set the boost
> +                        query.add(tq, false, false); // add to query
> +                    }
> +                }
> +                else {
> +                    break;
>                  }
> -                TermQuery tq = new TermQuery(term); // found a match
> -                tq.setBoost(getBoost());          // set the boost
> -                query.add(tq, false, false); // add to query
> -              }
> -            }
> -            else {
> -              break;
>              }
> -          }
> -          while (enumerator.next());
> -      } finally {
> -        enumerator.close();
> -      }
> -      return query;
> +            while (enumerator.next());
> +        }
> +        finally {
> +            enumerator.close();
> +        }
> +        return query;
>      }
>  
>      public Query combine(Query[] queries) {
> > /*
>  * Created on 05.09.2003
>  *
>  * To change the template for this generated file go to
>  * Window>Preferences>Java>Code Generation>Code and Comments
>  */
> package org.apache.lucene.search;
> 
> import java.io.IOException;
> 
> import org.apache.lucene.analysis.WhitespaceAnalyzer;
> import org.apache.lucene.document.Document;
> import org.apache.lucene.document.Field;
> import org.apache.lucene.index.IndexReader;
> import org.apache.lucene.index.IndexWriter;
> import org.apache.lucene.index.Term;
> import org.apache.lucene.store.Directory;
> import org.apache.lucene.store.RAMDirectory;
> 
> import junit.framework.TestCase;
> 
> /**
>  * 
>  * @author goller
>  */
> public class TestRangeQuery extends TestCase {
> 
>     
>     public TestRangeQuery() {
>         super();
>     }
> 
>     int docCount = 0;
>   
>     void addDoc(IndexWriter writer, String content)
>     {
>         
>       Document doc = new Document();
>     
>       doc.add(Field.Keyword("id","id" + docCount));
>       doc.add(Field.UnStored("content", content));
>     
>       try {
>         writer.addDocument(doc);
>       }
>       catch (IOException e) {
>         e.printStackTrace();
>       }
>       docCount++;
>       
>     }
>   
>     public void testNotInclusive(){
>         
>         Directory dir = new RAMDirectory();
>         IndexWriter writer = null;
>         Searcher searcher = null;
>         Query query = new RangeQuery(new Term("content", "A"), new
> Term("content", "C"), false);
>         Hits hits = null;
>         
>         try {
>           
>           writer  = new IndexWriter(dir, new WhitespaceAnalyzer(),
> true);
>           addDoc(writer, "A");
>           addDoc(writer, "B");
>           addDoc(writer, "C");
>           addDoc(writer, "D");
>           writer.close();
>           
>           searcher = new IndexSearcher(dir);
>           hits = searcher.search(query);
>           assertEquals(1, hits.length());
>           searcher.close();
>           
>           writer  = new IndexWriter(dir, new WhitespaceAnalyzer(),
> true);
>           addDoc(writer, "A");
>           addDoc(writer, "B");
>           addDoc(writer, "D");
>           writer.close();
>           
>           searcher = new IndexSearcher(dir);
>           hits = searcher.search(query);
>           assertEquals(1, hits.length());
>           searcher.close();
>           
>           writer  = new IndexWriter(dir, new WhitespaceAnalyzer(),
> false);
>           addDoc(writer, "C");
>           writer.close();
>           
>           searcher = new IndexSearcher(dir);
>           hits = searcher.search(query);
>           assertEquals(1, hits.length());
>           searcher.close();
>           
>         }
>         catch (IOException e) {
>           e.printStackTrace();
>         }
>         
>     }
>     
>     public void testInclusive(){
>         
>         Directory dir = new RAMDirectory();
>         IndexWriter writer = null;
>         Searcher searcher = null;
>         Query query = new RangeQuery(new Term("content", "A"), new
> Term("content", "C"), true);
>         Hits hits = null;
>         
>         try {
>           
>           writer  = new IndexWriter(dir, new WhitespaceAnalyzer(),
> true);
>           addDoc(writer, "A");
>           addDoc(writer, "B");
>           addDoc(writer, "C");
>           addDoc(writer, "D");
>           writer.close();
>           
>           searcher = new IndexSearcher(dir);
>           hits = searcher.search(query);
>           assertEquals(3, hits.length());
>           searcher.close();
>           
>           writer  = new IndexWriter(dir, new WhitespaceAnalyzer(),
> true);
>           addDoc(writer, "A");
>           addDoc(writer, "B");
>           addDoc(writer, "D");
>           writer.close();
>           
>           searcher = new IndexSearcher(dir);
>           hits = searcher.search(query);
>           assertEquals(2, hits.length());
>           searcher.close();
>           
>           writer  = new IndexWriter(dir, new WhitespaceAnalyzer(),
> false);
>           addDoc(writer, "C");
>           writer.close();
>           
>           searcher = new IndexSearcher(dir);
>           hits = searcher.search(query);
>           assertEquals(3, hits.length());
>           searcher.close();
>           
>         }
>         catch (IOException e) {
>           e.printStackTrace();
>         }
>         
>     }
> 
> 
> }
> 
> >
---------------------------------------------------------------------
> To unsubscribe, e-mail: lucene-dev-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: lucene-dev-help@jakarta.apache.org


__________________________________
Do you Yahoo!?
Yahoo! SiteBuilder - Free, easy-to-use web site design software
http://sitebuilder.yahoo.com