Home » lucene-3.0.1-src » org.apache » lucene » search » spans » [javadoc | source]

    1   package org.apache.lucene.search.spans;
    2   
    3   /**
    4    * Licensed to the Apache Software Foundation (ASF) under one or more
    5    * contributor license agreements.  See the NOTICE file distributed with
    6    * this work for additional information regarding copyright ownership.
    7    * The ASF licenses this file to You under the Apache License, Version 2.0
    8    * (the "License"); you may not use this file except in compliance with
    9    * the License.  You may obtain a copy of the License at
   10    *
   11    *     http://www.apache.org/licenses/LICENSE-2.0
   12    *
   13    * Unless required by applicable law or agreed to in writing, software
   14    * distributed under the License is distributed on an "AS IS" BASIS,
   15    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   16    * See the License for the specific language governing permissions and
   17    * limitations under the License.
   18    */
   19   
   20   import java.io.IOException;
   21   
   22   
   23   import java.util.List;
   24   import java.util.ArrayList;
   25   import java.util.Iterator;
   26   import java.util.Set;
   27   
   28   
   29   import org.apache.lucene.index.IndexReader;
   30   import org.apache.lucene.index.Term;
   31   import org.apache.lucene.search.Query;
   32   import org.apache.lucene.util.ToStringUtils;
   33   
   34   /** Matches spans which are near one another.  One can specify <i>slop</i>, the
   35    * maximum number of intervening unmatched positions, as well as whether
   36    * matches are required to be in-order. */
   37   public class SpanNearQuery extends SpanQuery implements Cloneable {
   38     protected List<SpanQuery> clauses;
   39     protected int slop;
   40     protected boolean inOrder;
   41   
   42     protected String field;
   43     private boolean collectPayloads;
   44   
   45     /** Construct a SpanNearQuery.  Matches spans matching a span from each
   46      * clause, with up to <code>slop</code> total unmatched positions between
   47      * them.  * When <code>inOrder</code> is true, the spans from each clause
   48      * must be * ordered as in <code>clauses</code>. */
   49     public SpanNearQuery(SpanQuery[] clauses, int slop, boolean inOrder) {
   50       this(clauses, slop, inOrder, true);     
   51     }
   52     
   53     public SpanNearQuery(SpanQuery[] clauses, int slop, boolean inOrder, boolean collectPayloads) {
   54   
   55       // copy clauses array into an ArrayList
   56       this.clauses = new ArrayList<SpanQuery>(clauses.length);
   57       for (int i = 0; i < clauses.length; i++) {
   58         SpanQuery clause = clauses[i];
   59         if (i == 0) {                               // check field
   60           field = clause.getField();
   61         } else if (!clause.getField().equals(field)) {
   62           throw new IllegalArgumentException("Clauses must have same field.");
   63         }
   64         this.clauses.add(clause);
   65       }
   66       this.collectPayloads = collectPayloads;
   67       this.slop = slop;
   68       this.inOrder = inOrder;
   69     }
   70   
   71     /** Return the clauses whose spans are matched. */
   72     public SpanQuery[] getClauses() {
   73       return clauses.toArray(new SpanQuery[clauses.size()]);
   74     }
   75   
   76     /** Return the maximum number of intervening unmatched positions permitted.*/
   77     public int getSlop() { return slop; }
   78   
   79     /** Return true if matches are required to be in-order.*/
   80     public boolean isInOrder() { return inOrder; }
   81   
   82     @Override
   83     public String getField() { return field; }
   84     
   85     @Override
   86     public void extractTerms(Set<Term> terms) {
   87   	    for (final SpanQuery clause : clauses) {
   88   	      clause.extractTerms(terms);
   89   	    }
   90     }  
   91     
   92   
   93     @Override
   94     public String toString(String field) {
   95       StringBuilder buffer = new StringBuilder();
   96       buffer.append("spanNear([");
   97       Iterator<SpanQuery> i = clauses.iterator();
   98       while (i.hasNext()) {
   99         SpanQuery clause = i.next();
  100         buffer.append(clause.toString(field));
  101         if (i.hasNext()) {
  102           buffer.append(", ");
  103         }
  104       }
  105       buffer.append("], ");
  106       buffer.append(slop);
  107       buffer.append(", ");
  108       buffer.append(inOrder);
  109       buffer.append(")");
  110       buffer.append(ToStringUtils.boost(getBoost()));
  111       return buffer.toString();
  112     }
  113   
  114     @Override
  115     public Spans getSpans(final IndexReader reader) throws IOException {
  116       if (clauses.size() == 0)                      // optimize 0-clause case
  117         return new SpanOrQuery(getClauses()).getSpans(reader);
  118   
  119       if (clauses.size() == 1)                      // optimize 1-clause case
  120         return clauses.get(0).getSpans(reader);
  121   
  122       return inOrder
  123               ? (Spans) new NearSpansOrdered(this, reader, collectPayloads)
  124               : (Spans) new NearSpansUnordered(this, reader);
  125     }
  126   
  127     @Override
  128     public Query rewrite(IndexReader reader) throws IOException {
  129       SpanNearQuery clone = null;
  130       for (int i = 0 ; i < clauses.size(); i++) {
  131         SpanQuery c = clauses.get(i);
  132         SpanQuery query = (SpanQuery) c.rewrite(reader);
  133         if (query != c) {                     // clause rewrote: must clone
  134           if (clone == null)
  135             clone = (SpanNearQuery) this.clone();
  136           clone.clauses.set(i,query);
  137         }
  138       }
  139       if (clone != null) {
  140         return clone;                        // some clauses rewrote
  141       } else {
  142         return this;                         // no clauses rewrote
  143       }
  144     }
  145     
  146     @Override
  147     public Object clone() {
  148       int sz = clauses.size();
  149       SpanQuery[] newClauses = new SpanQuery[sz];
  150   
  151       for (int i = 0; i < sz; i++) {
  152         newClauses[i] = (SpanQuery) clauses.get(i).clone();
  153       }
  154       SpanNearQuery spanNearQuery = new SpanNearQuery(newClauses, slop, inOrder);
  155       spanNearQuery.setBoost(getBoost());
  156       return spanNearQuery;
  157     }
  158   
  159     /** Returns true iff <code>o</code> is equal to this. */
  160     @Override
  161     public boolean equals(Object o) {
  162       if (this == o) return true;
  163       if (!(o instanceof SpanNearQuery)) return false;
  164   
  165       final SpanNearQuery spanNearQuery = (SpanNearQuery) o;
  166   
  167       if (inOrder != spanNearQuery.inOrder) return false;
  168       if (slop != spanNearQuery.slop) return false;
  169       if (!clauses.equals(spanNearQuery.clauses)) return false;
  170   
  171       return getBoost() == spanNearQuery.getBoost();
  172     }
  173   
  174     @Override
  175     public int hashCode() {
  176       int result;
  177       result = clauses.hashCode();
  178       // Mix bits before folding in things like boost, since it could cancel the
  179       // last element of clauses.  This particular mix also serves to
  180       // differentiate SpanNearQuery hashcodes from others.
  181       result ^= (result << 14) | (result >>> 19);  // reversible
  182       result += Float.floatToRawIntBits(getBoost());
  183       result += slop;
  184       result ^= (inOrder ? 0x99AFD3BD : 0);
  185       return result;
  186     }
  187   }

Home » lucene-3.0.1-src » org.apache » lucene » search » spans » [javadoc | source]