FileDocCategorySizeDatePackage
QueryUtils.javaAPI DocApache Lucene 2.2.07518Sat Jun 16 22:20:28 BST 2007org.apache.lucene.search

QueryUtils

public class QueryUtils extends Object
author
yonik

Fields Summary
Constructors Summary
Methods Summary
public static voidcheck(org.apache.lucene.search.Query q)
Check the types of things query objects should be able to do.

    checkHashEquals(q);
  
public static voidcheck(org.apache.lucene.search.Query q1, org.apache.lucene.search.Searcher s)
various query sanity checks on a searcher, including explanation checks.

see
#checkExplanations
see
#checkSkipTo
see
#check(Query)

    try {
      check(q1);
      if (s!=null) {
        if (s instanceof IndexSearcher) {
          IndexSearcher is = (IndexSearcher)s;
          checkFirstSkipTo(q1,is);
          checkSkipTo(q1,is);
        }
        checkExplanations(q1,s);
      }
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  
public static voidcheckEqual(org.apache.lucene.search.Query q1, org.apache.lucene.search.Query q2)

    TestCase.assertEquals(q1, q2);
    TestCase.assertEquals(q1.hashCode(), q2.hashCode());
  
public static voidcheckExplanations(org.apache.lucene.search.Query q, org.apache.lucene.search.Searcher s)
deep check that explanations of a query 'score' correctly

    CheckHits.checkExplanations(q, null, s, true);
  
private static voidcheckFirstSkipTo(org.apache.lucene.search.Query q, org.apache.lucene.search.IndexSearcher s)

    //System.out.println("checkFirstSkipTo: "+q);
    final float maxDiff = 1e-5f;
    final int lastDoc[] = {-1};
    s.search(q,new HitCollector() {
      public void collect(int doc, float score) {
        //System.out.println("doc="+doc);
        try {
          for (int i=lastDoc[0]+1; i<=doc; i++) {
            Weight w = q.weight(s);
            Scorer scorer = w.scorer(s.getIndexReader());
            TestCase.assertTrue("query collected "+doc+" but skipTo("+i+") says no more docs!",scorer.skipTo(i));
            TestCase.assertEquals("query collected "+doc+" but skipTo("+i+") got to "+scorer.doc(),doc,scorer.doc());
            float skipToScore = scorer.score();
            TestCase.assertEquals("unstable skipTo("+i+") score!",skipToScore,scorer.score(),maxDiff); 
            TestCase.assertEquals("query assigned doc "+doc+" a score of <"+score+"> but skipTo("+i+") has <"+skipToScore+">!",score,skipToScore,maxDiff);
          }
          lastDoc[0] = doc;
        } catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
    });
    Weight w = q.weight(s);
    Scorer scorer = w.scorer(s.getIndexReader());
    boolean more = scorer.skipTo(lastDoc[0]+1);
    if (more) 
      TestCase.assertFalse("query's last doc was "+lastDoc[0]+" but skipTo("+(lastDoc[0]+1)+") got to "+scorer.doc(),more);
  
public static voidcheckHashEquals(org.apache.lucene.search.Query q)
check very basic hashCode and equals

    Query q2 = (Query)q.clone();
    checkEqual(q,q2);

    Query q3 = (Query)q.clone();
    q3.setBoost(7.21792348f);
    checkUnequal(q,q3);

    // test that a class check is done so that no exception is thrown
    // in the implementation of equals()
    Query whacky = new Query() {
      public String toString(String field) {
        return "My Whacky Query";
      }
    };
    whacky.setBoost(q.getBoost());
    checkUnequal(q, whacky);
  
public static voidcheckSkipTo(org.apache.lucene.search.Query q, org.apache.lucene.search.IndexSearcher s)
alternate scorer skipTo(),skipTo(),next(),next(),skipTo(),skipTo(), etc and ensure a hitcollector receives same docs and scores

    //System.out.println("Checking "+q);
    
    if (BooleanQuery.getAllowDocsOutOfOrder()) return;  // in this case order of skipTo() might differ from that of next().

    final int skip_op = 0;
    final int next_op = 1;
    final int orders [][] = {
        {next_op},
        {skip_op},
        {skip_op, next_op},
        {next_op, skip_op},
        {skip_op, skip_op, next_op, next_op},
        {next_op, next_op, skip_op, skip_op},
        {skip_op, skip_op, skip_op, next_op, next_op},
    };
    for (int k = 0; k < orders.length; k++) {
      final int order[] = orders[k];
      //System.out.print("Order:");for (int i = 0; i < order.length; i++) System.out.print(order[i]==skip_op ? " skip()":" next()"); System.out.println();
      final int opidx[] = {0};

      final Weight w = q.weight(s);
      final Scorer scorer = w.scorer(s.getIndexReader());
      
      // FUTURE: ensure scorer.doc()==-1

      final int[] sdoc = new int[] {-1};
      final float maxDiff = 1e-5f;
      s.search(q,new HitCollector() {
        public void collect(int doc, float score) {
          try {
            int op = order[(opidx[0]++)%order.length];
            //System.out.println(op==skip_op ? "skip("+(sdoc[0]+1)+")":"next()");
            boolean more = op==skip_op ? scorer.skipTo(sdoc[0]+1) : scorer.next();
            sdoc[0] = scorer.doc();
            float scorerScore = scorer.score();
            float scorerScore2 = scorer.score();
            float scoreDiff = Math.abs(score-scorerScore);
            float scorerDiff = Math.abs(scorerScore2-scorerScore);
            if (!more || doc != sdoc[0] || scoreDiff>maxDiff || scorerDiff>maxDiff) {
              StringBuffer sbord = new StringBuffer();
              for (int i = 0; i < order.length; i++) 
                sbord.append(order[i]==skip_op ? " skip()":" next()");
              throw new RuntimeException("ERROR matching docs:"
                  +"\n\t"+(doc!=sdoc[0]?"--> ":"")+"doc="+sdoc[0]
                  +"\n\t"+(!more?"--> ":"")+"tscorer.more=" + more 
                  +"\n\t"+(scoreDiff>maxDiff?"--> ":"")+"scorerScore="+scorerScore+" scoreDiff="+scoreDiff + " maxDiff="+maxDiff
                  +"\n\t"+(scorerDiff>maxDiff?"--> ":"")+"scorerScore2="+scorerScore2+" scorerDiff="+scorerDiff
                  +"\n\thitCollector.doc=" + doc + " score="+score
                  +"\n\t Scorer=" + scorer
                  +"\n\t Query=" + q + "  "+q.getClass().getName()
                  +"\n\t Searcher=" + s
                  +"\n\t Order=" + sbord
                  +"\n\t Op=" + (op==skip_op ? " skip()":" next()")
              );
            }
          } catch (IOException e) {
            throw new RuntimeException(e);
          }
        }
      });
      
      // make sure next call to scorer is false.
      int op = order[(opidx[0]++)%order.length];
      //System.out.println(op==skip_op ? "last: skip()":"last: next()");
      boolean more = op==skip_op ? scorer.skipTo(sdoc[0]+1) : scorer.next();
      TestCase.assertFalse(more);
    }
  
public static voidcheckUnequal(org.apache.lucene.search.Query q1, org.apache.lucene.search.Query q2)

    TestCase.assertTrue(!q1.equals(q2));
    TestCase.assertTrue(!q2.equals(q1));

    // possible this test can fail on a hash collision... if that
    // happens, please change test to use a different example.
    TestCase.assertTrue(q1.hashCode() != q2.hashCode());