lucene-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dna...@apache.org
Subject cvs commit: jakarta-lucene/src/test/org/apache/lucene/queryParser TestMultiFieldQueryParser.java
Date Sun, 12 Dec 2004 15:27:50 GMT
dnaber      2004/12/12 07:27:49

  Modified:    src/java/org/apache/lucene/queryParser
                        MultiFieldQueryParser.java
  Added:       src/test/org/apache/lucene/queryParser
                        TestMultiFieldQueryParser.java
  Log:
  Deprecate the old constructors and the main parse(...) method. The new one now generates
a query that works
  as expected for both AND and OR mode. Also do better argument checking in the static methods
and throw
  IllegalArgumentException if something is wrong.
  
  Revision  Changes    Path
  1.7       +123 -18   jakarta-lucene/src/java/org/apache/lucene/queryParser/MultiFieldQueryParser.java
  
  Index: MultiFieldQueryParser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-lucene/src/java/org/apache/lucene/queryParser/MultiFieldQueryParser.java,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- MultiFieldQueryParser.java	27 Aug 2004 21:50:17 -0000	1.6
  +++ MultiFieldQueryParser.java	12 Dec 2004 15:27:49 -0000	1.7
  @@ -16,11 +16,9 @@
    * limitations under the License.
    */
   
  +import java.util.Vector;
  +
   import org.apache.lucene.analysis.Analyzer;
  -import org.apache.lucene.queryParser.CharStream;
  -import org.apache.lucene.queryParser.ParseException;
  -import org.apache.lucene.queryParser.QueryParser;
  -import org.apache.lucene.queryParser.QueryParserTokenManager;
   import org.apache.lucene.search.BooleanClause;
   import org.apache.lucene.search.BooleanQuery;
   import org.apache.lucene.search.Query;
  @@ -33,20 +31,121 @@
    */
   public class MultiFieldQueryParser extends QueryParser
   {
  +  
  +  private String[] fields;
  +
  +  /**
  +   * <p>Creates a MultiFieldQueryParser that will, when parse(String query)
  +   * is called, construct a query like this (assuming the query consists of
  +   * two terms and you specify the two fields <code>title</code> and <code>body</code>):</p>
  +   * 
  +   * <code>
  +   * (title:term1 body:term1) (title:term2 body:term2)
  +   * </code>
  +   *
  +   * <p>When setDefaultOperator(AND_OPERATOR) is set, the result will be:</p>
  +   *  
  +   * <code>
  +   * +(title:term1 body:term1) +(title:term2 body:term2)
  +   * </code>
  +   * 
  +   * <p>In other words, all the query's terms must appear, but it doesn't matter
in
  +   * what fields they appear.</p>
  +   */
  +  public MultiFieldQueryParser(String[] fields, Analyzer analyzer) {
  +    super(null, analyzer);
  +    this.fields = fields;
  +  }
  +  
  +  protected Query getFieldQuery(String field, Analyzer analyzer, String queryText)
  +      throws ParseException {
  +    if (field == null) {
  +      Vector clauses = new Vector();
  +      for (int i = 0; i < fields.length; i++)
  +        clauses.add(new BooleanClause(super.getFieldQuery(fields[i], queryText),
  +            BooleanClause.Occur.SHOULD));
  +      return getBooleanQuery(clauses);
  +    }
  +    return super.getFieldQuery(field, queryText);
  +  }
  +  
  +  /**
  +   * @deprecated use {@link #getFuzzyQuery(String, String, float)}
  +   */
  +  protected Query getFuzzyQuery(String field, String termStr) throws ParseException {
  +    return getFuzzyQuery(field, termStr, fuzzyMinSim);
  +  }
  +
  +  protected Query getFuzzyQuery(String field, String termStr, float minSimilarity) throws
ParseException
  +  {
  +    if (field == null) {
  +      Vector clauses = new Vector();
  +      for (int i = 0; i < fields.length; i++) {
  +        clauses.add(new BooleanClause(super.getFuzzyQuery(fields[i], termStr, minSimilarity),
  +            BooleanClause.Occur.SHOULD));
  +      }
  +      return getBooleanQuery(clauses);
  +    }
  +    return super.getFuzzyQuery(field, termStr, minSimilarity);
  +  }
  +
  +  protected Query getPrefixQuery(String field, String termStr) throws ParseException
  +  {
  +    if (field == null) {
  +      Vector clauses = new Vector();
  +      for (int i = 0; i < fields.length; i++) {
  +        clauses.add(new BooleanClause(super.getPrefixQuery(fields[i], termStr),
  +            BooleanClause.Occur.SHOULD));
  +      }
  +      return getBooleanQuery(clauses);
  +    }
  +    return super.getPrefixQuery(field, termStr);
  +  }
  +
  +  /** @throws ParseException
  +   * @deprecated use {@link #getRangeQuery(String, String, String, boolean)}
  +  */
  +  protected Query getRangeQuery(String field, Analyzer analyzer, 
  +      String part1, String part2, boolean inclusive) throws ParseException {
  +   return getRangeQuery(field, part1, part2, inclusive);
  +  }
  + 
  +  protected Query getRangeQuery(String field, String part1, String part2, boolean inclusive)
throws ParseException {
  +    if (field == null) {
  +      Vector clauses = new Vector();
  +      for (int i = 0; i < fields.length; i++) {
  +        clauses.add(new BooleanClause(super.getRangeQuery(fields[i], part1, part2, inclusive),
  +            BooleanClause.Occur.SHOULD));
  +      }
  +      return getBooleanQuery(clauses);
  +    }
  +    return super.getRangeQuery(field, part1, part2, inclusive);
  +  }
  + 
  +
       public static final int NORMAL_FIELD     = 0;
       public static final int REQUIRED_FIELD   = 1;
       public static final int PROHIBITED_FIELD = 2;
   
  +    /**
  +     * @deprecated use {@link #MultiFieldQueryParser(String[], Analyzer)} instead
  +     */
       public MultiFieldQueryParser(QueryParserTokenManager tm)
       {
           super(tm);
       }
   
  +    /**
  +     * @deprecated use {@link #MultiFieldQueryParser(String[], Analyzer)} instead
  +     */
       public MultiFieldQueryParser(CharStream stream)
       {
           super(stream);
       }
   
  +    /**
  +     * @deprecated use {@link #MultiFieldQueryParser(String[], Analyzer)} instead
  +     */
       public MultiFieldQueryParser(String f, Analyzer a)
       {
           super(f, a);
  @@ -68,6 +167,7 @@
        * @param analyzer Analyzer to use
        * @throws ParseException if query parsing fails
        * @throws TokenMgrError if query parsing fails
  +     * @deprecated use {@link #parse(String)} instead
        */
       public static Query parse(String query, String[] fields, Analyzer analyzer)
   	throws ParseException
  @@ -96,13 +196,14 @@
        * @param analyzer Analyzer to use
        * @throws ParseException if query parsing fails
        * @throws TokenMgrError if query parsing fails
  +     * @throws IllegalArgumentException if the length of the queries array differs
  +     *  from the length of the fields array
        */
       public static Query parse(String[] queries, String[] fields,
           Analyzer analyzer) throws ParseException
       {
           if (queries.length != fields.length)
  -            // TODO Exception handling
  -            throw new ParseException("queries.length != fields.length");
  +            throw new IllegalArgumentException("queries.length != fields.length");
           BooleanQuery bQuery = new BooleanQuery();
           for (int i = 0; i < fields.length; i++)
           {
  @@ -121,9 +222,9 @@
        * Usage:
        * <code>
        * String[] fields = {"filename", "contents", "description"};
  -     * int[] flags = {MultiFieldQueryParser.NORMAL FIELD,
  -     *                MultiFieldQueryParser.REQUIRED FIELD,
  -     *                MultiFieldQueryParser.PROHIBITED FIELD,};
  +     * int[] flags = {MultiFieldQueryParser.NORMAL_FIELD,
  +     *                MultiFieldQueryParser.REQUIRED_FIELD,
  +     *                MultiFieldQueryParser.PROHIBITED_FIELD,};
        * parse(query, fields, flags, analyzer);
        * </code>
        * </pre>
  @@ -141,11 +242,14 @@
        * @param analyzer Analyzer to use
        * @throws ParseException if query parsing fails
        * @throws TokenMgrError if query parsing fails
  +     * @throws IllegalArgumentException if the length of the fields array differs
  +     *  from the length of the flags array
        */
       public static Query parse(String query, String[] fields, int[] flags,
  -	Analyzer analyzer)
  -	throws ParseException
  +	Analyzer analyzer) throws ParseException
       {
  +        if (fields.length != flags.length)
  +          throw new IllegalArgumentException("fields.length != flags.length");
           BooleanQuery bQuery = new BooleanQuery();
           for (int i = 0; i < fields.length; i++)
           {
  @@ -176,9 +280,9 @@
        * Usage:
        * <code>
        * String[] fields = {"filename", "contents", "description"};
  -     * int[] flags = {MultiFieldQueryParser.NORMAL FIELD,
  -     *                MultiFieldQueryParser.REQUIRED FIELD,
  -     *                MultiFieldQueryParser.PROHIBITED FIELD,};
  +     * int[] flags = {MultiFieldQueryParser.NORMAL_FIELD,
  +     *                MultiFieldQueryParser.REQUIRED_FIELD,
  +     *                MultiFieldQueryParser.PROHIBITED_FIELD,};
        * parse(query, fields, flags, analyzer);
        * </code>
        * </pre>
  @@ -196,13 +300,14 @@
        * @param analyzer Analyzer to use
        * @throws ParseException if query parsing fails
        * @throws TokenMgrError if query parsing fails
  +     * @throws IllegalArgumentException if the length of the queries, fields,
  +     *  and flags array differ
        */
       public static Query parse(String[] queries, String[] fields, int[] flags,
           Analyzer analyzer) throws ParseException
       {
  -        if (queries.length != fields.length)
  -            // TODO Exception handling
  -            throw new ParseException("queries.length != fields.length");
  +        if (!(queries.length == fields.length && queries.length == flags.length))
  +            throw new IllegalArgumentException("queries, fields, and flags array have have
different length");
           BooleanQuery bQuery = new BooleanQuery();
           for (int i = 0; i < fields.length; i++)
           {
  
  
  
  1.1                  jakarta-lucene/src/test/org/apache/lucene/queryParser/TestMultiFieldQueryParser.java
  
  Index: TestMultiFieldQueryParser.java
  ===================================================================
  package org.apache.lucene.queryParser;
  
  /**
   * Copyright 2004 The Apache Software Foundation
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  import junit.framework.TestCase;
  
  import org.apache.lucene.analysis.standard.StandardAnalyzer;
  import org.apache.lucene.search.Query;
  
  /**
   * Tests QueryParser.
   * @author Daniel Naber
   */
  public class TestMultiFieldQueryParser extends TestCase {
  
    public void testSimple() throws Exception {
      String[] fields = {"b", "t"};
      MultiFieldQueryParser mfqp = new MultiFieldQueryParser(fields, new StandardAnalyzer());
      
      Query q = mfqp.parse("one");
      assertEquals("b:one t:one", q.toString());
      
      q = mfqp.parse("one two");
      assertEquals("(b:one t:one) (b:two t:two)", q.toString());
      
      q = mfqp.parse("+one +two");
      assertEquals("+(b:one t:one) +(b:two t:two)", q.toString());
  
      q = mfqp.parse("+one -two -three)");
      assertEquals("+(b:one t:one) -(b:two t:two) -(b:three t:three)", q.toString());
      
      q = mfqp.parse("one^2 two");
      assertEquals("((b:one t:one)^2.0) (b:two t:two)", q.toString());
  
      q = mfqp.parse("one~ two");
      assertEquals("(b:one~0.5 t:one~0.5) (b:two t:two)", q.toString());
  
      q = mfqp.parse("one~0.8 two^2");
      assertEquals("(b:one~0.8 t:one~0.8) ((b:two t:two)^2.0)", q.toString());
  
      q = mfqp.parse("one* two*");
      assertEquals("(b:one* t:one*) (b:two* t:two*)", q.toString());
  
      q = mfqp.parse("[a TO c] two");
      assertEquals("(b:[a TO c] t:[a TO c]) (b:two t:two)", q.toString());
  
      // make sure that terms which have a field are not touched:
      q = mfqp.parse("one f:two");
      assertEquals("(b:one t:one) f:two", q.toString());
  
      // AND mode:
      mfqp.setDefaultOperator(QueryParser.AND_OPERATOR);
      q = mfqp.parse("one two");
      assertEquals("+(b:one t:one) +(b:two t:two)", q.toString());
  
    }
    
    // TODO: remove this for Lucene 2.0
    public void testOldMethods() throws ParseException {
      // testing the old static calls that are now deprecated:
      assertQueryEquals("b:one t:one", "one");
      assertQueryEquals("(b:one b:two) (t:one t:two)", "one two");
      assertQueryEquals("(b:one -b:two) (t:one -t:two)", "one -two");
      assertQueryEquals("(b:one -(b:two b:three)) (t:one -(t:two t:three))", "one -(two three)");
      assertQueryEquals("(+b:one +b:two) (+t:one +t:two)", "+one +two");
    }
    
    // TODO: remove this for Lucene 2.0
    private void assertQueryEquals(String expected, String query) throws ParseException {
      String[] fields = {"b", "t"};
      Query q = MultiFieldQueryParser.parse(query, fields, new StandardAnalyzer());
      String s = q.toString();
      assertEquals(expected, s);
    }
  
    public void testStaticMethod1() throws ParseException {
      String[] fields = {"b", "t"};
      String[] queries = {"one", "two"};
      Query q = MultiFieldQueryParser.parse(queries, fields, new StandardAnalyzer());
      assertEquals("b:one t:two", q.toString());
  
      String[] queries2 = {"+one", "+two"};
      q = MultiFieldQueryParser.parse(queries2, fields, new StandardAnalyzer());
      assertEquals("(+b:one) (+t:two)", q.toString());
  
      String[] queries3 = {"one", "+two"};
      q = MultiFieldQueryParser.parse(queries3, fields, new StandardAnalyzer());
      assertEquals("b:one (+t:two)", q.toString());
  
      String[] queries4 = {"one +more", "+two"};
      q = MultiFieldQueryParser.parse(queries4, fields, new StandardAnalyzer());
      assertEquals("(b:one +b:more) (+t:two)", q.toString());
  
      String[] queries5 = {"blah"};
      try {
        q = MultiFieldQueryParser.parse(queries5, fields, new StandardAnalyzer());
        fail();
      } catch(IllegalArgumentException e) {
        // expected exception, array length differs
      }
    }
    
    public void testStaticMethod2() throws ParseException {
      String[] fields = {"b", "t"};
      int[] flags = {MultiFieldQueryParser.REQUIRED_FIELD, MultiFieldQueryParser.PROHIBITED_FIELD};
      Query q = MultiFieldQueryParser.parse("one", fields, flags, new StandardAnalyzer());
      assertEquals("+b:one -t:one", q.toString());
  
      q = MultiFieldQueryParser.parse("one two", fields, flags, new StandardAnalyzer());
      assertEquals("+(b:one b:two) -(t:one t:two)", q.toString());
  
      try {
        int[] flags2 = {MultiFieldQueryParser.REQUIRED_FIELD};
        q = MultiFieldQueryParser.parse("blah", fields, flags2, new StandardAnalyzer());
        fail();
      } catch(IllegalArgumentException e) {
        // expected exception, array length differs
      }
    }
  
    public void testStaticMethod3() throws ParseException {
      String[] queries = {"one", "two"};
      String[] fields = {"b", "t"};
      int[] flags = {MultiFieldQueryParser.REQUIRED_FIELD, MultiFieldQueryParser.PROHIBITED_FIELD};
      Query q = MultiFieldQueryParser.parse(queries, fields, flags, new StandardAnalyzer());
      assertEquals("+b:one -t:two", q.toString());
  
      try {
        int[] flags2 = {MultiFieldQueryParser.REQUIRED_FIELD};
        q = MultiFieldQueryParser.parse(queries, fields, flags2, new StandardAnalyzer());
        fail();
      } catch(IllegalArgumentException e) {
        // expected exception, array length differs
      }
    }
  
  }
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: lucene-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: lucene-dev-help@jakarta.apache.org


Mime
View raw message