Save This Page
Home » lucene-3.0.1-src » org.apache » lucene » search » [javadoc | source]
    1   package org.apache.lucene.search;
    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   import java.util.Set;
   22   
   23   import org.apache.lucene.index.Term;
   24   import org.apache.lucene.index.TermDocs;
   25   import org.apache.lucene.index.IndexReader;
   26   import org.apache.lucene.search.Explanation.IDFExplanation;
   27   import org.apache.lucene.util.ToStringUtils;
   28   
   29   /** A Query that matches documents containing a term.
   30     This may be combined with other terms with a {@link BooleanQuery}.
   31     */
   32   public class TermQuery extends Query {
   33     private Term term;
   34   
   35     private class TermWeight extends Weight {
   36       private Similarity similarity;
   37       private float value;
   38       private float idf;
   39       private float queryNorm;
   40       private float queryWeight;
   41       private IDFExplanation idfExp;
   42   
   43       public TermWeight(Searcher searcher)
   44         throws IOException {
   45         this.similarity = getSimilarity(searcher);
   46         idfExp = similarity.idfExplain(term, searcher);
   47         idf = idfExp.getIdf();
   48       }
   49   
   50       @Override
   51       public String toString() { return "weight(" + TermQuery.this + ")"; }
   52   
   53       @Override
   54       public Query getQuery() { return TermQuery.this; }
   55   
   56       @Override
   57       public float getValue() { return value; }
   58   
   59       @Override
   60       public float sumOfSquaredWeights() {
   61         queryWeight = idf * getBoost();             // compute query weight
   62         return queryWeight * queryWeight;           // square it
   63       }
   64   
   65       @Override
   66       public void normalize(float queryNorm) {
   67         this.queryNorm = queryNorm;
   68         queryWeight *= queryNorm;                   // normalize query weight
   69         value = queryWeight * idf;                  // idf for document
   70       }
   71   
   72       @Override
   73       public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException {
   74         TermDocs termDocs = reader.termDocs(term);
   75   
   76         if (termDocs == null)
   77           return null;
   78   
   79         return new TermScorer(this, termDocs, similarity, reader.norms(term.field()));
   80       }
   81   
   82       @Override
   83       public Explanation explain(IndexReader reader, int doc)
   84         throws IOException {
   85   
   86         ComplexExplanation result = new ComplexExplanation();
   87         result.setDescription("weight("+getQuery()+" in "+doc+"), product of:");
   88   
   89         Explanation expl = new Explanation(idf, idfExp.explain());
   90   
   91         // explain query weight
   92         Explanation queryExpl = new Explanation();
   93         queryExpl.setDescription("queryWeight(" + getQuery() + "), product of:");
   94   
   95         Explanation boostExpl = new Explanation(getBoost(), "boost");
   96         if (getBoost() != 1.0f)
   97           queryExpl.addDetail(boostExpl);
   98         queryExpl.addDetail(expl);
   99   
  100         Explanation queryNormExpl = new Explanation(queryNorm,"queryNorm");
  101         queryExpl.addDetail(queryNormExpl);
  102   
  103         queryExpl.setValue(boostExpl.getValue() *
  104                            expl.getValue() *
  105                            queryNormExpl.getValue());
  106   
  107         result.addDetail(queryExpl);
  108   
  109         // explain field weight
  110         String field = term.field();
  111         ComplexExplanation fieldExpl = new ComplexExplanation();
  112         fieldExpl.setDescription("fieldWeight("+term+" in "+doc+
  113                                  "), product of:");
  114   
  115         Explanation tfExplanation = new Explanation();
  116         int tf = 0;
  117         TermDocs termDocs = reader.termDocs(term);
  118         if (termDocs != null) {
  119           try {
  120             if (termDocs.skipTo(doc) && termDocs.doc() == doc) {
  121               tf = termDocs.freq();
  122             }
  123           } finally {
  124             termDocs.close();
  125           }
  126           tfExplanation.setValue(similarity.tf(tf));
  127           tfExplanation.setDescription("tf(termFreq("+term+")="+tf+")");
  128         } else {
  129           tfExplanation.setValue(0.0f);
  130           tfExplanation.setDescription("no matching term");
  131         }
  132         fieldExpl.addDetail(tfExplanation);
  133         fieldExpl.addDetail(expl);
  134   
  135         Explanation fieldNormExpl = new Explanation();
  136         byte[] fieldNorms = reader.norms(field);
  137         float fieldNorm =
  138           fieldNorms!=null ? Similarity.decodeNorm(fieldNorms[doc]) : 1.0f;
  139         fieldNormExpl.setValue(fieldNorm);
  140         fieldNormExpl.setDescription("fieldNorm(field="+field+", doc="+doc+")");
  141         fieldExpl.addDetail(fieldNormExpl);
  142         
  143         fieldExpl.setMatch(Boolean.valueOf(tfExplanation.isMatch()));
  144         fieldExpl.setValue(tfExplanation.getValue() *
  145                            expl.getValue() *
  146                            fieldNormExpl.getValue());
  147   
  148         result.addDetail(fieldExpl);
  149         result.setMatch(fieldExpl.getMatch());
  150         
  151         // combine them
  152         result.setValue(queryExpl.getValue() * fieldExpl.getValue());
  153   
  154         if (queryExpl.getValue() == 1.0f)
  155           return fieldExpl;
  156   
  157         return result;
  158       }
  159     }
  160   
  161     /** Constructs a query for the term <code>t</code>. */
  162     public TermQuery(Term t) {
  163       term = t;
  164     }
  165   
  166     /** Returns the term of this query. */
  167     public Term getTerm() { return term; }
  168   
  169     @Override
  170     public Weight createWeight(Searcher searcher) throws IOException {
  171       return new TermWeight(searcher);
  172     }
  173   
  174     @Override
  175     public void extractTerms(Set<Term> terms) {
  176       terms.add(getTerm());
  177     }
  178   
  179     /** Prints a user-readable version of this query. */
  180     @Override
  181     public String toString(String field) {
  182       StringBuilder buffer = new StringBuilder();
  183       if (!term.field().equals(field)) {
  184         buffer.append(term.field());
  185         buffer.append(":");
  186       }
  187       buffer.append(term.text());
  188       buffer.append(ToStringUtils.boost(getBoost()));
  189       return buffer.toString();
  190     }
  191   
  192     /** Returns true iff <code>o</code> is equal to this. */
  193     @Override
  194     public boolean equals(Object o) {
  195       if (!(o instanceof TermQuery))
  196         return false;
  197       TermQuery other = (TermQuery)o;
  198       return (this.getBoost() == other.getBoost())
  199         && this.term.equals(other.term);
  200     }
  201   
  202     /** Returns a hash code value for this object.*/
  203     @Override
  204     public int hashCode() {
  205       return Float.floatToIntBits(getBoost()) ^ term.hashCode();
  206     }
  207   
  208   }

Save This Page
Home » lucene-3.0.1-src » org.apache » lucene » search » [javadoc | source]