LUCENE-5136: improve FacetRequest javadocs

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1507194 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Shai Erera 2013-07-26 05:01:44 +00:00
parent 6e56ccd030
commit c74f89adc4
1 changed files with 99 additions and 102 deletions

View File

@ -2,6 +2,7 @@ package org.apache.lucene.facet.search;
import java.io.IOException;
import org.apache.lucene.facet.params.CategoryListParams.OrdinalPolicy;
import org.apache.lucene.facet.taxonomy.CategoryPath;
import org.apache.lucene.facet.taxonomy.TaxonomyReader;
@ -23,30 +24,36 @@ import org.apache.lucene.facet.taxonomy.TaxonomyReader;
*/
/**
* Request to accumulate facet information for a specified facet and possibly
* also some of its descendants, upto a specified depth.
* Defines an aggregation request for a category. Allows specifying the
* {@link #numResults number of child categories} to return as well as
* {@link #getSortOrder() which} categories to consider the "top" (highest or
* lowest ranking ones).
* <p>
* The facet request additionally defines what information should
* be computed within the facet results, if and how should results
* be ordered, etc.
* <P>
* An example facet request is to look at all sub-categories of "Author", and
* return the 10 with the highest counts (sorted by decreasing count).
* If the category being aggregated is hierarchical, you can also specify the
* {@link #setDepth(int) depth} up which to aggregate child categories as well
* as how the result should be {@link #setResultMode(ResultMode) constructed}.
*
* @lucene.experimental
*/
public abstract class FacetRequest {
/**
* Result structure manner of applying request's limits such as
* {@link FacetRequest#getNumLabel()} and {@link FacetRequest#numResults}.
* Only relevant when {@link FacetRequest#getDepth()} is &gt; 1.
* When {@link FacetRequest#getDepth()} is greater than 1, defines the
* structure of the result as well as how constraints such as
* {@link FacetRequest#numResults} and {@link FacetRequest#getNumLabel()} are
* applied.
*/
public enum ResultMode {
/** Limits are applied per node, and the result has a full tree structure. */
/**
* Constraints are applied per node, and the result has a full tree
* structure. Default result mode.
*/
PER_NODE_IN_TREE,
/** Limits are applied globally, on total number of results, and the result has a flat structure. */
/**
* Constraints are applied globally, on total number of results, and the
* result has a flat structure.
*/
GLOBAL_FLAT
}
@ -54,59 +61,50 @@ public abstract class FacetRequest {
* Specifies which array of {@link FacetArrays} should be used to resolve
* values. When set to {@link #INT} or {@link #FLOAT}, allows creating an
* optimized {@link FacetResultsHandler}, which does not call
* {@link FacetRequest#getValueOf(FacetArrays, int)} for every ordinals.
* {@link FacetRequest#getValueOf(FacetArrays, int)} for every ordinal.
* <p>
* If set to {@link #BOTH}, the {@link FacetResultsHandler} will use
* {@link FacetRequest#getValueOf(FacetArrays, int)} to resolve ordinal
* values, although it is recommended that you consider writing a specialized
* {@link FacetResultsHandler}.
* <p>
* Can also be set to {@link #NONE}, to indicate that this
* {@link FacetRequest} does not use {@link FacetArrays} to aggregate its
* result categories. Such requests won't use {@link FacetResultsHandler}.
*/
public enum FacetArraysSource { INT, FLOAT, BOTH }
public enum FacetArraysSource { INT, FLOAT, BOTH, NONE }
/** Requested sort order for the results. */
/**
* Defines which categories to return. If {@link #DESCENDING} (the default),
* the highest {@link FacetRequest#numResults} weighted categories will be
* returned, otherwise the lowest ones.
*/
public enum SortOrder { ASCENDING, DESCENDING }
/**
* Default depth for facets accumulation.
* @see #getDepth()
*/
public static final int DEFAULT_DEPTH = 1;
/**
* Default result mode
* @see #getResultMode()
*/
public static final ResultMode DEFAULT_RESULT_MODE = ResultMode.PER_NODE_IN_TREE;
/** The category being aggregated in this facet request. */
public final CategoryPath categoryPath;
/** The number of child categories to return for {@link #categoryPath}. */
public final int numResults;
private int numLabel;
private int depth;
private SortOrder sortOrder;
private int depth = 1;
private SortOrder sortOrder = SortOrder.DESCENDING;
private ResultMode resultMode = ResultMode.PER_NODE_IN_TREE;
/**
* Computed at construction, this hashCode is based on two final members
* {@link CategoryPath} and <code>numResults</code>
*/
// Computed at construction; based on categoryPath and numResults.
private final int hashCode;
private ResultMode resultMode = DEFAULT_RESULT_MODE;
/**
* Initialize the request with a given path, and a requested number of facets
* results. By default, all returned results would be labeled - to alter this
* default see {@link #setNumLabel(int)}.
* <p>
* <b>NOTE:</b> if <code>numResults</code> is given as
* <code>Integer.MAX_VALUE</code> than all the facet results would be
* returned, without any limit.
* <p>
* <b>NOTE:</b> it is assumed that the given {@link CategoryPath} is not
* modified after construction of this object. Otherwise, some things may not
* function properly, e.g. {@link #hashCode()}.
* Constructor with the given category to aggregate and the number of child
* categories to return.
*
* @throws IllegalArgumentException if numResults is &le; 0
* @param path
* the category to aggregate. Cannot be {@code null}.
* @param numResults
* the number of child categories to return. If set to
* {@code Integer.MAX_VALUE}, all immediate child categories will be
* returned. Must be greater than 0.
*/
public FacetRequest(CategoryPath path, int numResults) {
if (numResults <= 0) {
@ -118,9 +116,6 @@ public abstract class FacetRequest {
categoryPath = path;
this.numResults = numResults;
numLabel = numResults;
depth = DEFAULT_DEPTH;
sortOrder = SortOrder.DESCENDING;
hashCode = categoryPath.hashCode() ^ this.numResults;
}
@ -147,123 +142,125 @@ public abstract class FacetRequest {
@Override
public boolean equals(Object o) {
if (o instanceof FacetRequest) {
FacetRequest that = (FacetRequest)o;
return that.hashCode == this.hashCode &&
FacetRequest that = (FacetRequest) o;
return that.hashCode == this.hashCode &&
that.categoryPath.equals(this.categoryPath) &&
that.numResults == this.numResults &&
that.depth == this.depth &&
that.resultMode == this.resultMode &&
that.numLabel == this.numLabel;
that.numLabel == this.numLabel &&
that.sortOrder == this.sortOrder;
}
return false;
}
/**
* How deeply to look under the given category. If the depth is 0,
* only the category itself is counted. If the depth is 1, its immediate
* children are also counted, and so on. If the depth is Integer.MAX_VALUE,
* all the category's descendants are counted.<br>
* How deeply to look under {@link #categoryPath}. By default, only its
* immediate children are aggregated (depth=1). If set to
* {@code Integer.MAX_VALUE}, the entire sub-tree of the category will be
* aggregated.
* <p>
* <b>NOTE:</b> setting depth to 0 means that only the category itself should
* be aggregated. In that case, make sure to index the category with
* {@link OrdinalPolicy#ALL_PARENTS}, unless it is not the root category (the
* dimension), in which case {@link OrdinalPolicy#ALL_BUT_DIMENSION} is fine
* too.
*/
public final int getDepth() {
// TODO add AUTO_EXPAND option
// TODO an AUTO_EXPAND option could be useful
return depth;
}
/**
* Returns the {@link FacetArraysSource} this {@link FacetRequest} uses in
* Returns the {@link FacetArraysSource} this request uses in
* {@link #getValueOf(FacetArrays, int)}.
*/
public abstract FacetArraysSource getFacetArraysSource();
/**
* If getNumLabel() &lt; getNumResults(), only the first getNumLabel() results
* will have their category paths calculated, and the rest will only be
* available as ordinals (category numbers) and will have null paths.
* <P>
* If Integer.MAX_VALUE is specified, all results are labled.
* <P>
* The purpose of this parameter is to avoid having to run the whole faceted
* search again when the user asks for more values for the facet; The
* application can ask (getNumResults()) for more values than it needs to
* show, but keep getNumLabel() only the number it wants to immediately show.
* The slow-down caused by finding more values is negligible, because the
* slowest part - finding the categories' paths, is avoided.
* Allows to specify the number of categories to label. By default all
* returned categories are labeled.
* <p>
* Depending on the {@link #getResultMode() LimitsMode}, this limit is applied
* globally or per results node. In the global mode, if this limit is 3, only
* 3 top results would be labeled. In the per-node mode, if this limit is 3, 3
* top children of {@link #categoryPath the target category} would be labeled,
* as well as 3 top children of each of them, and so forth, until the depth
* defined by {@link #getDepth()}.
*
* @see #getResultMode()
* This allows an app to request a large number of results to return, while
* labeling them on-demand (e.g. when the UI requests to show more
* categories).
*/
public final int getNumLabel() {
return numLabel;
}
/** Return the requested result mode. */
/** Return the requested result mode (defaults to {@link ResultMode#PER_NODE_IN_TREE}. */
public final ResultMode getResultMode() {
return resultMode;
}
/** Return the requested order of results. */
/** Return the requested order of results (defaults to {@link SortOrder#DESCENDING}. */
public final SortOrder getSortOrder() {
return sortOrder;
}
/**
* Return the value of a category used for facets computations for this
* request. For a count request this would be the count for that facet, i.e.
* an integer number. but for other requests this can be the result of a more
* complex operation, and the result can be any double precision number.
* Having this method with a general name <b>value</b> which is double
* precision allows to have more compact API and code for handling counts and
* perhaps other requests (such as for associations) very similarly, and by
* the same code and API, avoiding code duplication.
* Return the weight of the requested category ordinal. A {@link FacetRequest}
* is responsible for resolving the weight of a category given the
* {@link FacetArrays} and {@link #getFacetArraysSource()}. E.g. a counting
* request will probably return the value of the category from
* {@link FacetArrays#getIntArray()} while an average-weighting request will
* compute the value using both arrays.
*
* @param arrays
* provider for facet arrays in use for current computation.
* @param idx
* an index into the count arrays now in effect in
* <code>arrays</code>. E.g., for ordinal number <i>n</i>, with
* partition, of size <i>partitionSize</i>, now covering <i>n</i>,
* <code>getValueOf</code> would be invoked with <code>idx</code>
* being <i>n</i> % <i>partitionSize</i>.
* the arrays used to aggregate the categories weights.
* @param ordinal
* the category ordinal for which to return the weight.
*/
// TODO perhaps instead of getValueOf we can have a postProcess(FacetArrays)
// That, together with getFacetArraysSource should allow ResultHandlers to
// efficiently obtain the values from the arrays directly
public abstract double getValueOf(FacetArrays arrays, int idx);
public abstract double getValueOf(FacetArrays arrays, int ordinal);
@Override
public int hashCode() {
return hashCode;
}
/**
* Sets the depth up to which to aggregate facets.
*
* @see #getDepth()
*/
public void setDepth(int depth) {
this.depth = depth;
}
/**
* Sets the number of categories to label.
*
* @see #getNumLabel()
*/
public void setNumLabel(int numLabel) {
this.numLabel = numLabel;
}
/**
* @param resultMode the resultMode to set
* Sets the {@link ResultMode} for this request.
*
* @see #getResultMode()
*/
public void setResultMode(ResultMode resultMode) {
this.resultMode = resultMode;
}
/**
* Sets the {@link SortOrder} for this request.
*
* @see #getSortOrder()
*/
public void setSortOrder(SortOrder sortOrder) {
this.sortOrder = sortOrder;
}
@Override
public String toString() {
return categoryPath.toString()+" nRes="+numResults+" nLbl="+numLabel;
return categoryPath.toString() + " nRes=" + numResults + " nLbl=" + numLabel;
}
}