alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Lucene example source code file (FilteredQuery.java)

This example Lucene source code file (FilteredQuery.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Lucene tags/keywords

docidsetiterator, explanation, filter, filteredquery, io, ioexception, ioexception, no_more_docs, no_more_docs, override, override, query, query, scorer, util, weight

The Lucene FilteredQuery.java source code

package org.apache.lucene.search;

/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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 org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.util.ToStringUtils;

import java.io.IOException;
import java.util.Set;


/**
 * A query that applies a filter to the results of another query.
 *
 * <p>Note: the bits are retrieved from the filter each time this
 * query is used in a search - use a CachingWrapperFilter to avoid
 * regenerating the bits every time.
 *
 * <p>Created: Apr 20, 2004 8:58:29 AM
 *
 * @since   1.4
 * @see     CachingWrapperFilter
 */
public class FilteredQuery
extends Query {

  Query query;
  Filter filter;

  /**
   * Constructs a new query which applies a filter to the results of the original query.
   * Filter.getDocIdSet() will be called every time this query is used in a search.
   * @param query  Query to be filtered, cannot be <code>null.
   * @param filter Filter to apply to query results, cannot be <code>null.
   */
  public FilteredQuery (Query query, Filter filter) {
    this.query = query;
    this.filter = filter;
  }

  /**
   * Returns a Weight that applies the filter to the enclosed query's Weight.
   * This is accomplished by overriding the Scorer returned by the Weight.
   */
  @Override
  public Weight createWeight(final Searcher searcher) throws IOException {
    final Weight weight = query.createWeight (searcher);
    final Similarity similarity = query.getSimilarity(searcher);
    return new Weight() {
      private float value;
        
      // pass these methods through to enclosed query's weight
      @Override
      public float getValue() { return value; }
      
      @Override
      public float sumOfSquaredWeights() throws IOException { 
        return weight.sumOfSquaredWeights() * getBoost() * getBoost(); 
      }

      @Override
      public void normalize (float v) { 
        weight.normalize(v);
        value = weight.getValue() * getBoost();
      }

      @Override
      public Explanation explain (IndexReader ir, int i) throws IOException {
        Explanation inner = weight.explain (ir, i);
        if (getBoost()!=1) {
          Explanation preBoost = inner;
          inner = new Explanation(inner.getValue()*getBoost(),"product of:");
          inner.addDetail(new Explanation(getBoost(),"boost"));
          inner.addDetail(preBoost);
        }
        Filter f = FilteredQuery.this.filter;
        DocIdSet docIdSet = f.getDocIdSet(ir);
        DocIdSetIterator docIdSetIterator = docIdSet == null ? DocIdSet.EMPTY_DOCIDSET.iterator() : docIdSet.iterator();
        if (docIdSetIterator == null) {
          docIdSetIterator = DocIdSet.EMPTY_DOCIDSET.iterator();
        }
        if (docIdSetIterator.advance(i) == i) {
          return inner;
        } else {
          Explanation result = new Explanation
            (0.0f, "failure to match filter: " + f.toString());
          result.addDetail(inner);
          return result;
        }
      }

      // return this query
      @Override
      public Query getQuery() { return FilteredQuery.this; }

      // return a filtering scorer
      @Override
      public Scorer scorer(IndexReader indexReader, boolean scoreDocsInOrder, boolean topScorer)
          throws IOException {
        final Scorer scorer = weight.scorer(indexReader, true, false);
        if (scorer == null) {
          return null;
        }
        DocIdSet docIdSet = filter.getDocIdSet(indexReader);
        if (docIdSet == null) {
          return null;
        }
        final DocIdSetIterator docIdSetIterator = docIdSet.iterator();
        if (docIdSetIterator == null) {
          return null;
        }

        return new Scorer(similarity, this) {

          private int doc = -1;
          
          private int advanceToCommon(int scorerDoc, int disiDoc) throws IOException {
            while (scorerDoc != disiDoc) {
              if (scorerDoc < disiDoc) {
                scorerDoc = scorer.advance(disiDoc);
              } else {
                disiDoc = docIdSetIterator.advance(scorerDoc);
              }
            }
            return scorerDoc;
          }

          @Override
          public int nextDoc() throws IOException {
            int scorerDoc, disiDoc;
            return doc = (disiDoc = docIdSetIterator.nextDoc()) != NO_MORE_DOCS
                && (scorerDoc = scorer.nextDoc()) != NO_MORE_DOCS
                && advanceToCommon(scorerDoc, disiDoc) != NO_MORE_DOCS ? scorer.docID() : NO_MORE_DOCS;
          }
          
          @Override
          public int docID() { return doc; }
          
          @Override
          public int advance(int target) throws IOException {
            int disiDoc, scorerDoc;
            return doc = (disiDoc = docIdSetIterator.advance(target)) != NO_MORE_DOCS
                && (scorerDoc = scorer.advance(disiDoc)) != NO_MORE_DOCS 
                && advanceToCommon(scorerDoc, disiDoc) != NO_MORE_DOCS ? scorer.docID() : NO_MORE_DOCS;
          }

          @Override
          public float score() throws IOException { return getBoost() * scorer.score(); }
        };
      }
    };
  }

  /** Rewrites the wrapped query. */
  @Override
  public Query rewrite(IndexReader reader) throws IOException {
    Query rewritten = query.rewrite(reader);
    if (rewritten != query) {
      FilteredQuery clone = (FilteredQuery)this.clone();
      clone.query = rewritten;
      return clone;
    } else {
      return this;
    }
  }

  public Query getQuery() {
    return query;
  }

  public Filter getFilter() {
    return filter;
  }

  // inherit javadoc
  @Override
  public void extractTerms(Set<Term> terms) {
      getQuery().extractTerms(terms);
  }

  /** Prints a user-readable version of this query. */
  @Override
  public String toString (String s) {
    StringBuilder buffer = new StringBuilder();
    buffer.append("filtered(");
    buffer.append(query.toString(s));
    buffer.append(")->");
    buffer.append(filter);
    buffer.append(ToStringUtils.boost(getBoost()));
    return buffer.toString();
  }

  /** Returns true iff <code>o is equal to this. */
  @Override
  public boolean equals(Object o) {
    if (o instanceof FilteredQuery) {
      FilteredQuery fq = (FilteredQuery) o;
      return (query.equals(fq.query) && filter.equals(fq.filter) && getBoost()==fq.getBoost());
    }
    return false;
  }

  /** Returns a hash code value for this object. */
  @Override
  public int hashCode() {
    return query.hashCode() ^ filter.hashCode() + Float.floatToRawIntBits(getBoost());
  }
}

Other Lucene examples (source code examples)

Here is a short list of links related to this Lucene FilteredQuery.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.