io.quarkus.redis.datasource.search.AggregateArgs Maven / Gradle / Ivy
Show all versions of quarkus-redis-client Show documentation
package io.quarkus.redis.datasource.search;
import static io.quarkus.redis.runtime.datasource.Validation.notNullOrBlank;
import static io.smallrye.mutiny.helpers.ParameterValidation.doesNotContainNull;
import static io.smallrye.mutiny.helpers.ParameterValidation.nonNull;
import static io.smallrye.mutiny.helpers.ParameterValidation.positive;
import static io.smallrye.mutiny.helpers.ParameterValidation.validate;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import io.quarkus.redis.datasource.RedisCommandExtraArguments;
/**
* Represents the extra arguments of the {@code ft.aggregate} command.
*/
public class AggregateArgs implements RedisCommandExtraArguments {
private boolean verbatim;
private final Map fields = new HashMap<>();
private boolean loadAllFields;
private Duration timeout;
private final List clauses = new ArrayList<>();
private int offset = -1;
private int count = -1;
private final Map params = new HashMap<>();
private int dialect = -1;
private int cursorCount = -1;
private Duration cursorMaxIdle;
private boolean cursor;
/**
* If set, does not try to use stemming for query expansion but searches the query terms verbatim.
*
* @return the current {@code AggregateArgs}
*/
public AggregateArgs verbatim() {
this.verbatim = true;
return this;
}
/**
* Loads all the document attributes from the source documents.
*
* @return the current {@code AggregateArgs}
*/
public AggregateArgs allFields() {
loadAllFields = true;
return this;
}
/**
* Adds the given attribute to the list of attribute loaded from the document source.
* You can pass the list of identifier, being either an attribute name for hashes and JSON or a JSON Path expression
* for JSON.
* The alias is the optional name used in the result. If it is not provided, the identifier is used. This should be avoided.
*
* Attributes needed for aggregations should be stored as {@code SORTABLE}, where they are available to the
* aggregation pipeline with very low latency. LOAD hurts the performance of aggregate queries considerably because
* every processed record needs to execute the equivalent of {@code HMGET} against a Redis key, which when executed
* over millions of keys, amounts to high processing times.
*
* @param field the field
* @param alias the alias (optional but recommended)
* @return the current {@code AggregateArgs}
*/
public AggregateArgs field(String field, String alias) {
fields.put(notNullOrBlank(field, "field"), alias);
return this;
}
/**
* Adds the given attribute to the list of attribute loaded from the document source.
* You can pass the list of identifier, being either an attribute name for hashes and JSON or a JSON Path expression
* for JSON.
*
* Attributes needed for aggregations should be stored as {@code SORTABLE}, where they are available to the
* aggregation pipeline with very low latency. LOAD hurts the performance of aggregate queries considerably because
* every processed record needs to execute the equivalent of {@code HMGET} against a Redis key, which when executed
* over millions of keys, amounts to high processing times.
*
* @param field the field
* @return the current {@code AggregateArgs}
*/
public AggregateArgs field(String field) {
fields.put(notNullOrBlank(field, "field"), null);
return this;
}
/**
* Overrides the timeout parameter of the module.
*
* @param timeout the timeout
* @return the current {@code AggregateArgs}
*/
public AggregateArgs timeout(Duration timeout) {
this.timeout = validate(timeout, "timeout");
return this;
}
/**
* Groups the results in the pipeline based on one or more properties.
* Each group should have at least one reducer, a function that handles the group entries, either counting them,
* or performing multiple aggregate operations.
*
* @param groupBy the group by clause
* @return the current {@code AggregateArgs}
*/
public AggregateArgs groupBy(GroupBy groupBy) {
clauses.add(nonNull(groupBy, "groupBy"));
return this;
}
/**
* Sorts the pipeline up until the point of {@code SORTBY}, using the given property and the ascending order.
*
* @param sortBy the sort by clause
* @return the current {@code AggregateArgs}
*/
public AggregateArgs sortBy(SortBy sortBy) {
clauses.add(nonNull(sortBy, "sortBy"));
return this;
}
/**
* Applies a 1-to-1 transformation on one or more properties and either stores the result as a new property down
* the pipeline or replaces any property using this transformation.
*
* {@code expression} is an expression that can be used to perform arithmetic operations on numeric properties,
* or functions that can be applied on properties depending on their types, or any combination thereof.
*
* For example, APPLY "sqrt(@foo)/log(@bar) + 5" AS baz evaluates this expression dynamically for each record in
* the pipeline and store the result as a new property called baz, which can be referenced by further
* APPLY/SORTBY/GROUPBY/REDUCE operations down the pipeline.
*
* @param apply the Apply clause
* @return the current {@code AggregateArgs}
*/
public AggregateArgs apply(Apply apply) {
clauses.add(nonNull(apply, "apply"));
return this;
}
/**
* Limits the number of results to return just num results starting at index offset (zero-based).
* It is much more efficient to use {@code SORTBY … MAX} if you are interested in just limiting the output of a
* sort operation.
*
* @param offset the offset
* @param count the count
* @return the current {@code AggregateArgs}
*/
public AggregateArgs limit(int offset, int count) {
this.offset = positive(offset, "offset");
this.count = positive(count, "count");
return this;
}
/**
* Filters the results using predicate expressions relating to values in each result.
* They are applied post query and relate to the current state of the pipeline.
*
* @param filter the filter
* @return the current {@code AggregateArgs}
*/
public AggregateArgs filter(String filter) {
clauses.add(new Filter(notNullOrBlank(filter, "filter")));
return this;
}
/**
* Defines one or more value parameters. Each parameter has a name and a value.
* You can reference parameters in the query by a $, followed by the parameter name, for example, $user.
* Each such reference in the search query to a parameter name is substituted by the corresponding parameter value.
* For example, with parameter definition PARAMS 4 lon 29.69465 lat 34.95126, the expression @loc:[$lon $lat 10 km]
* is evaluated to @loc:[29.69465 34.95126 10 km]. You cannot reference parameters in the query string where concrete
* values are not allowed, such as in field names, for example, @loc.
*
* To use PARAMS, set DIALECT to 2.
*
* @param name the parameter name
* @param value the parameter value
* @return the current {@code AggregateArgs}
*/
public AggregateArgs param(String name, Object value) {
this.params.put(notNullOrBlank(name, "name"), nonNull(value, "value"));
return this;
}
/**
* Selects the dialect version under which to execute the query. If not specified, the query will execute under
* the default dialect version set during module initial loading.
*
* @param version the version
* @return the current {@code AggregateArgs}
*/
public AggregateArgs dialect(int version) {
this.dialect = version;
return this;
}
/**
* Scan part of the results with a quicker alternative than {@code LIMIT}.
*
* @return the current {@code AggregateArgs}
*/
public AggregateArgs withCursor() {
this.cursor = true;
return this;
}
/**
* When using a cursor, configure the number of result.
*
* @param count the number of result to fetch in one go.
* @return the current {@code AggregateArgs}
*/
public AggregateArgs cursorCount(int count) {
this.cursorCount = positive(count, "count");
return this;
}
/**
* When using a cursor, configure the max idle duration.
*
* @param maxIdleDuration the max idle duration of the cursor.
* @return the current {@code AggregateArgs}
*/
public AggregateArgs cursorMaxIdleTime(Duration maxIdleDuration) {
this.cursorMaxIdle = validate(maxIdleDuration, "maxIdleDuration");
return this;
}
@Override
public List