All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.pageseeder.flint.lucene.search.FieldFacet Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2015 Allette Systems (Australia)
 * http://www.allette.com.au
 *
 * 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.
 */
package org.pageseeder.flint.lucene.search;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.pageseeder.flint.lucene.facet.FlexibleFieldFacet;
import org.pageseeder.flint.lucene.util.Bucket;
import org.pageseeder.flint.lucene.util.Bucket.Entry;
import org.pageseeder.xmlwriter.XMLWritable;
import org.pageseeder.xmlwriter.XMLWriter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * A facet implementation using a simple index field.
 *
 * @deprecated use {@link FlexibleFieldFacet}
 *
 * @author Christophe Lauret
 * @version 16 February 2012
 */
public final class FieldFacet implements XMLWritable, Facet {

  /**
   * The default number of facet values if not specified.
   */
  public static final int DEFAULT_MAX_NUMBER_OF_VALUES = 10;

  /**
   * The name of this facet
   */
  private final String _name;

  /**
   * The queries used to calculate each facet.
   */
  private final List _queries;

  /**
   * The queries used to calculate each facet.
   */
  private transient Bucket _bucket;

  /**
   * Creates a new facet with the specified name;
   *
   * @param name    The name of the facet.
   * @param queries The subqueries to use on top of the base query to calculate the facet values.
   */
  private FieldFacet(String name, List queries) {
    this._name = name;
    this._queries = queries;
  }

  /**
   * Returns the name of the field.
   * @return the name of the field.
   */
  @Override
  public String name() {
    return this._name;
  }

  /**
   * Returns the query for given value if the specified value matches the text for the term.
   *
   * @param value the text of the term to match.
   * @return the requested query if it exists or null.
   */
  @Override
  public Query forValue(String value) {
    if (value == null) return null;
    for (TermQuery t : this._queries) {
      if (value.equals(t.getTerm().text())) return t;
    }
    // Why null?
    return new TermQuery(new Term(this._name, value));
  }

  /**
   * Computes each facet option.
   *
   * @param searcher the index search to use.
   * @param base     the base query.
   * @param size     the maximum number of field values to compute.
   *
   * @throws IOException if thrown by the searcher.
   */
  public void compute(IndexSearcher searcher, Query base, int size) throws IOException {
    // If the base is null, simply calculate for each query
    if (base == null) {
      compute(searcher, size);
    } else {
      if (size < 0) throw new IllegalArgumentException("size < 0");
      // Otherwise, make a boolean query of the base AND each facet query
      Bucket bucket = new Bucket<>(size);
      DocumentCounter counter = new DocumentCounter();
      for (TermQuery q : this._queries) {
        BooleanQuery.Builder query = new BooleanQuery.Builder();
        query.add(base, Occur.MUST);
        query.add(q, Occur.MUST);
        searcher.search(query.build(), counter);
        bucket.add(q.getTerm(), counter.getCount());
        counter.reset();
      }
      this._bucket = bucket;
    }
  }

  @Override
  public void compute(IndexSearcher searcher, Query base, List filters) throws IOException {
    compute(searcher, base);
  }

  /**
   * Computes each facet option.
   *
   * 

Same as compute(searcher, base, 10);. * *

Defaults to 10. * * @param searcher the index search to use. * @param base the base query. * * @throws IOException if thrown by the searcher. */ @Override public void compute(IndexSearcher searcher, Query base) throws IOException { compute(searcher, base, DEFAULT_MAX_NUMBER_OF_VALUES); } /** * Computes each facet option without a base query. * * @param searcher the index search to use. * @param size the number of facet values to calculate. * * @throws IOException if thrown by the searcher. */ public void compute(IndexSearcher searcher, int size) throws IOException { Bucket bucket = new Bucket<>(size); DocumentCounter counter = new DocumentCounter(); for (TermQuery q : this._queries) { searcher.search(q, counter); bucket.add(q.getTerm(), counter.getCount()); counter.reset(); } this._bucket = bucket; } @Override public void toXML(XMLWriter xml) throws IOException { xml.openElement("facet", true); xml.attribute("name", this._name); xml.attribute("type", "field"); xml.attribute("computed", Boolean.toString(this._bucket != null)); if (this._bucket != null) { xml.attribute("total", this._bucket.getConsidered()); for (Entry e : this._bucket.entrySet()) { xml.openElement("term"); xml.attribute("field", e.item().field()); xml.attribute("text", e.item().text()); xml.attribute("cardinality", e.count()); xml.closeElement(); } } xml.closeElement(); } public Bucket getValues() { return this._bucket; } // Static helpers ------------------------------------------------------------------------------- /** * Creates a new facet for the specified field. * * @param field the field for this facet. * @param reader the reader to use. * * @return the corresponding Facet ready to use with a base query. * * @throws IOException if thrown by the reader. */ public static FieldFacet newFacet(String field, IndexReader reader) throws IOException { List terms = Terms.terms(reader, field); List subs = new ArrayList<>(terms.size()); for (Term t : terms) { subs.add(new TermQuery(t)); } return new FieldFacet(field, subs); } /** * Creates a new facet for the specified field. * * @param field the field for this facet. * @param reader the reader to use. * * @return the corresponding Facet ready to use with a base query. * * @throws IOException if thrown by the reader. */ public static FieldFacet newFacet(String field, IndexReader reader, int maxValues) throws IOException { List terms = Terms.terms(reader, field); if (terms.size() > maxValues) return null; List subs = new ArrayList<>(terms.size()); for (Term t : terms) { subs.add(new TermQuery(t)); } return new FieldFacet(field, subs); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy