mirror of https://github.com/apache/lucene.git
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:
parent
6e56ccd030
commit
c74f89adc4
|
@ -2,6 +2,7 @@ package org.apache.lucene.facet.search;
|
||||||
|
|
||||||
import java.io.IOException;
|
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.CategoryPath;
|
||||||
import org.apache.lucene.facet.taxonomy.TaxonomyReader;
|
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
|
* Defines an aggregation request for a category. Allows specifying the
|
||||||
* also some of its descendants, upto a specified depth.
|
* {@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>
|
* <p>
|
||||||
* The facet request additionally defines what information should
|
* If the category being aggregated is hierarchical, you can also specify the
|
||||||
* be computed within the facet results, if and how should results
|
* {@link #setDepth(int) depth} up which to aggregate child categories as well
|
||||||
* be ordered, etc.
|
* as how the result should be {@link #setResultMode(ResultMode) constructed}.
|
||||||
* <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).
|
|
||||||
*
|
*
|
||||||
* @lucene.experimental
|
* @lucene.experimental
|
||||||
*/
|
*/
|
||||||
public abstract class FacetRequest {
|
public abstract class FacetRequest {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Result structure manner of applying request's limits such as
|
* When {@link FacetRequest#getDepth()} is greater than 1, defines the
|
||||||
* {@link FacetRequest#getNumLabel()} and {@link FacetRequest#numResults}.
|
* structure of the result as well as how constraints such as
|
||||||
* Only relevant when {@link FacetRequest#getDepth()} is > 1.
|
* {@link FacetRequest#numResults} and {@link FacetRequest#getNumLabel()} are
|
||||||
|
* applied.
|
||||||
*/
|
*/
|
||||||
public enum ResultMode {
|
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,
|
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
|
GLOBAL_FLAT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,59 +61,50 @@ public abstract class FacetRequest {
|
||||||
* Specifies which array of {@link FacetArrays} should be used to resolve
|
* Specifies which array of {@link FacetArrays} should be used to resolve
|
||||||
* values. When set to {@link #INT} or {@link #FLOAT}, allows creating an
|
* values. When set to {@link #INT} or {@link #FLOAT}, allows creating an
|
||||||
* optimized {@link FacetResultsHandler}, which does not call
|
* optimized {@link FacetResultsHandler}, which does not call
|
||||||
* {@link FacetRequest#getValueOf(FacetArrays, int)} for every ordinals.
|
* {@link FacetRequest#getValueOf(FacetArrays, int)} for every ordinal.
|
||||||
* <p>
|
* <p>
|
||||||
* If set to {@link #BOTH}, the {@link FacetResultsHandler} will use
|
* If set to {@link #BOTH}, the {@link FacetResultsHandler} will use
|
||||||
* {@link FacetRequest#getValueOf(FacetArrays, int)} to resolve ordinal
|
* {@link FacetRequest#getValueOf(FacetArrays, int)} to resolve ordinal
|
||||||
* values, although it is recommended that you consider writing a specialized
|
* values, although it is recommended that you consider writing a specialized
|
||||||
* {@link FacetResultsHandler}.
|
* {@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 }
|
public enum SortOrder { ASCENDING, DESCENDING }
|
||||||
|
|
||||||
/**
|
/** The category being aggregated in this facet request. */
|
||||||
* 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;
|
|
||||||
|
|
||||||
public final CategoryPath categoryPath;
|
public final CategoryPath categoryPath;
|
||||||
|
|
||||||
|
/** The number of child categories to return for {@link #categoryPath}. */
|
||||||
public final int numResults;
|
public final int numResults;
|
||||||
|
|
||||||
private int numLabel;
|
private int numLabel;
|
||||||
private int depth;
|
private int depth = 1;
|
||||||
private SortOrder sortOrder;
|
private SortOrder sortOrder = SortOrder.DESCENDING;
|
||||||
|
private ResultMode resultMode = ResultMode.PER_NODE_IN_TREE;
|
||||||
|
|
||||||
/**
|
// Computed at construction; based on categoryPath and numResults.
|
||||||
* Computed at construction, this hashCode is based on two final members
|
|
||||||
* {@link CategoryPath} and <code>numResults</code>
|
|
||||||
*/
|
|
||||||
private final int hashCode;
|
private final int hashCode;
|
||||||
|
|
||||||
private ResultMode resultMode = DEFAULT_RESULT_MODE;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the request with a given path, and a requested number of facets
|
* Constructor with the given category to aggregate and the number of child
|
||||||
* results. By default, all returned results would be labeled - to alter this
|
* categories to return.
|
||||||
* 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()}.
|
|
||||||
*
|
*
|
||||||
* @throws IllegalArgumentException if numResults is ≤ 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) {
|
public FacetRequest(CategoryPath path, int numResults) {
|
||||||
if (numResults <= 0) {
|
if (numResults <= 0) {
|
||||||
|
@ -118,9 +116,6 @@ public abstract class FacetRequest {
|
||||||
categoryPath = path;
|
categoryPath = path;
|
||||||
this.numResults = numResults;
|
this.numResults = numResults;
|
||||||
numLabel = numResults;
|
numLabel = numResults;
|
||||||
depth = DEFAULT_DEPTH;
|
|
||||||
sortOrder = SortOrder.DESCENDING;
|
|
||||||
|
|
||||||
hashCode = categoryPath.hashCode() ^ this.numResults;
|
hashCode = categoryPath.hashCode() ^ this.numResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,123 +142,125 @@ public abstract class FacetRequest {
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (o instanceof FacetRequest) {
|
if (o instanceof FacetRequest) {
|
||||||
FacetRequest that = (FacetRequest)o;
|
FacetRequest that = (FacetRequest) o;
|
||||||
return that.hashCode == this.hashCode &&
|
return that.hashCode == this.hashCode &&
|
||||||
that.categoryPath.equals(this.categoryPath) &&
|
that.categoryPath.equals(this.categoryPath) &&
|
||||||
that.numResults == this.numResults &&
|
that.numResults == this.numResults &&
|
||||||
that.depth == this.depth &&
|
that.depth == this.depth &&
|
||||||
that.resultMode == this.resultMode &&
|
that.resultMode == this.resultMode &&
|
||||||
that.numLabel == this.numLabel;
|
that.numLabel == this.numLabel &&
|
||||||
|
that.sortOrder == this.sortOrder;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How deeply to look under the given category. If the depth is 0,
|
* How deeply to look under {@link #categoryPath}. By default, only its
|
||||||
* only the category itself is counted. If the depth is 1, its immediate
|
* immediate children are aggregated (depth=1). If set to
|
||||||
* children are also counted, and so on. If the depth is Integer.MAX_VALUE,
|
* {@code Integer.MAX_VALUE}, the entire sub-tree of the category will be
|
||||||
* all the category's descendants are counted.<br>
|
* 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() {
|
public final int getDepth() {
|
||||||
// TODO add AUTO_EXPAND option
|
// TODO an AUTO_EXPAND option could be useful
|
||||||
return depth;
|
return depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the {@link FacetArraysSource} this {@link FacetRequest} uses in
|
* Returns the {@link FacetArraysSource} this request uses in
|
||||||
* {@link #getValueOf(FacetArrays, int)}.
|
* {@link #getValueOf(FacetArrays, int)}.
|
||||||
*/
|
*/
|
||||||
public abstract FacetArraysSource getFacetArraysSource();
|
public abstract FacetArraysSource getFacetArraysSource();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If getNumLabel() < getNumResults(), only the first getNumLabel() results
|
* Allows to specify the number of categories to label. By default all
|
||||||
* will have their category paths calculated, and the rest will only be
|
* returned categories are labeled.
|
||||||
* 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.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Depending on the {@link #getResultMode() LimitsMode}, this limit is applied
|
* This allows an app to request a large number of results to return, while
|
||||||
* globally or per results node. In the global mode, if this limit is 3, only
|
* labeling them on-demand (e.g. when the UI requests to show more
|
||||||
* 3 top results would be labeled. In the per-node mode, if this limit is 3, 3
|
* categories).
|
||||||
* 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()
|
|
||||||
*/
|
*/
|
||||||
public final int getNumLabel() {
|
public final int getNumLabel() {
|
||||||
return numLabel;
|
return numLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the requested result mode. */
|
/** Return the requested result mode (defaults to {@link ResultMode#PER_NODE_IN_TREE}. */
|
||||||
public final ResultMode getResultMode() {
|
public final ResultMode getResultMode() {
|
||||||
return resultMode;
|
return resultMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return the requested order of results. */
|
/** Return the requested order of results (defaults to {@link SortOrder#DESCENDING}. */
|
||||||
public final SortOrder getSortOrder() {
|
public final SortOrder getSortOrder() {
|
||||||
return sortOrder;
|
return sortOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the value of a category used for facets computations for this
|
* Return the weight of the requested category ordinal. A {@link FacetRequest}
|
||||||
* request. For a count request this would be the count for that facet, i.e.
|
* is responsible for resolving the weight of a category given the
|
||||||
* an integer number. but for other requests this can be the result of a more
|
* {@link FacetArrays} and {@link #getFacetArraysSource()}. E.g. a counting
|
||||||
* complex operation, and the result can be any double precision number.
|
* request will probably return the value of the category from
|
||||||
* Having this method with a general name <b>value</b> which is double
|
* {@link FacetArrays#getIntArray()} while an average-weighting request will
|
||||||
* precision allows to have more compact API and code for handling counts and
|
* compute the value using both arrays.
|
||||||
* perhaps other requests (such as for associations) very similarly, and by
|
|
||||||
* the same code and API, avoiding code duplication.
|
|
||||||
*
|
*
|
||||||
* @param arrays
|
* @param arrays
|
||||||
* provider for facet arrays in use for current computation.
|
* the arrays used to aggregate the categories weights.
|
||||||
* @param idx
|
* @param ordinal
|
||||||
* an index into the count arrays now in effect in
|
* the category ordinal for which to return the weight.
|
||||||
* <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>.
|
|
||||||
*/
|
*/
|
||||||
// TODO perhaps instead of getValueOf we can have a postProcess(FacetArrays)
|
// TODO perhaps instead of getValueOf we can have a postProcess(FacetArrays)
|
||||||
// That, together with getFacetArraysSource should allow ResultHandlers to
|
// That, together with getFacetArraysSource should allow ResultHandlers to
|
||||||
// efficiently obtain the values from the arrays directly
|
// 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
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return hashCode;
|
return hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the depth up to which to aggregate facets.
|
||||||
|
*
|
||||||
|
* @see #getDepth()
|
||||||
|
*/
|
||||||
public void setDepth(int depth) {
|
public void setDepth(int depth) {
|
||||||
this.depth = depth;
|
this.depth = depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the number of categories to label.
|
||||||
|
*
|
||||||
|
* @see #getNumLabel()
|
||||||
|
*/
|
||||||
public void setNumLabel(int numLabel) {
|
public void setNumLabel(int numLabel) {
|
||||||
this.numLabel = numLabel;
|
this.numLabel = numLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param resultMode the resultMode to set
|
* Sets the {@link ResultMode} for this request.
|
||||||
|
*
|
||||||
* @see #getResultMode()
|
* @see #getResultMode()
|
||||||
*/
|
*/
|
||||||
public void setResultMode(ResultMode resultMode) {
|
public void setResultMode(ResultMode resultMode) {
|
||||||
this.resultMode = resultMode;
|
this.resultMode = resultMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link SortOrder} for this request.
|
||||||
|
*
|
||||||
|
* @see #getSortOrder()
|
||||||
|
*/
|
||||||
public void setSortOrder(SortOrder sortOrder) {
|
public void setSortOrder(SortOrder sortOrder) {
|
||||||
this.sortOrder = sortOrder;
|
this.sortOrder = sortOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return categoryPath.toString()+" nRes="+numResults+" nLbl="+numLabel;
|
return categoryPath.toString() + " nRes=" + numResults + " nLbl=" + numLabel;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue