
com.mongodb.client.model.WindowedComputations Maven / Gradle / Ivy
/*
* Copyright 2008-present MongoDB, Inc.
*
* 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 com.mongodb.client.model;
import com.mongodb.annotations.Beta;
import com.mongodb.client.model.Windows.Bound;
import com.mongodb.lang.Nullable;
import org.bson.BsonDocument;
import org.bson.BsonDocumentWriter;
import org.bson.BsonType;
import org.bson.codecs.configuration.CodecRegistry;
import org.bson.conversions.Bson;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import static com.mongodb.assertions.Assertions.assertNotNull;
import static com.mongodb.assertions.Assertions.isTrueArgument;
import static org.bson.assertions.Assertions.notNull;
/**
* Builders for {@linkplain WindowedComputation windowed computations} used in the
* {@link Aggregates#setWindowFields(Object, Bson, List) $setWindowFields} pipeline stage
* of an aggregation pipeline. Each windowed computation is a triple:
*
* - A window function. Some functions require documents in a window to be sorted
* (see {@code sortBy} in {@link Aggregates#setWindowFields(Object, Bson, List)}).
* - An optional {@linkplain Window window}, a.k.a. frame.
* Specifying {@code null} window is equivalent to specifying an unbounded window,
* i.e., a window with both ends specified as {@link Bound#UNBOUNDED}.
* Some window functions require to specify an explicit unbounded window instead of specifying {@code null}.
* - A path to an output field to be computed by the window function over the window.
*
* A windowed computation is similar to an {@linkplain Accumulators accumulator} but does not result in folding documents constituting
* the window into a single document.
*
* @mongodb.driver.manual meta/aggregation-quick-reference/#field-paths Field paths
* @since 4.3
* @mongodb.server.release 5.0
*/
@Beta
public final class WindowedComputations {
/**
* Creates a windowed computation from a document field in situations when there is no builder method that better satisfies your needs.
* This method cannot be used to validate the document field syntax.
*
* Example
* The following code creates two functionally equivalent windowed computations,
* though they may not be {@linkplain #equals(Object) equal}.
*
{@code
* Window pastWeek = Windows.timeRange(-1, MongoTimeUnit.WEEK, Windows.Bound.CURRENT);
* WindowedComputation pastWeekExpenses1 = WindowedComputations.sum("pastWeekExpenses", "$expenses", pastWeek);
* WindowedComputation pastWeekExpenses2 = WindowedComputations.of(
* new BsonField("pastWeekExpenses", new Document("$sum", "$expenses")
* .append("window", pastWeek.toBsonDocument())));
* }
*
* @param windowedComputation A document field representing the required windowed computation.
* @return The constructed windowed computation.
*/
public static WindowedComputation of(final BsonField windowedComputation) {
return new BsonFieldWindowedComputation(notNull("windowedComputation", windowedComputation));
}
/**
* Builds a computation of the sum of the evaluation results of the {@code expression} over the {@code window}.
*
* @param path The output field path.
* @param expression The expression.
* @param window The window.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-sum $sum
*/
public static WindowedComputation sum(final String path, final TExpression expression, @Nullable final Window window) {
notNull("path", path);
notNull("expression", expression);
return simpleParameterWindowFunction(path, "$sum", expression, window);
}
/**
* Builds a computation of the average of the evaluation results of the {@code expression} over the {@code window}.
*
* @param path The output field path.
* @param expression The expression.
* @param window The window.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-avg $avg
*/
public static WindowedComputation avg(final String path, final TExpression expression, @Nullable final Window window) {
notNull("path", path);
notNull("expression", expression);
return simpleParameterWindowFunction(path, "$avg", expression, window);
}
/**
* Builds a computation of the sample standard deviation of the evaluation results of the {@code expression} over the {@code window}.
*
* @param path The output field path.
* @param expression The expression.
* @param window The window.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-std-dev-samp $stdDevSamp
*/
public static WindowedComputation stdDevSamp(final String path, final TExpression expression,
@Nullable final Window window) {
notNull("path", path);
notNull("expression", expression);
return simpleParameterWindowFunction(path, "$stdDevSamp", expression, window);
}
/**
* Builds a computation of the population standard deviation of the evaluation results of the {@code expression}
* over the {@code window}.
*
* @param path The output field path.
* @param expression The expression.
* @param window The window.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-std-dev-pop $stdDevPop
*/
public static WindowedComputation stdDevPop(final String path, final TExpression expression,
@Nullable final Window window) {
notNull("path", path);
notNull("expression", expression);
return simpleParameterWindowFunction(path, "$stdDevPop", expression, window);
}
/**
* Builds a computation of the lowest of the evaluation results of the {@code expression} over the {@code window}.
*
* @param path The output field path.
* @param expression The expression.
* @param window The window.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-min $min
*/
public static WindowedComputation min(final String path, final TExpression expression, @Nullable final Window window) {
notNull("path", path);
notNull("expression", expression);
return simpleParameterWindowFunction(path, "$min", expression, window);
}
/**
* Builds a computation of the highest of the evaluation results of the {@code expression} over the {@code window}.
*
* @param path The output field path.
* @param expression The expression.
* @param window The window.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-max $max
*/
public static WindowedComputation max(final String path, final TExpression expression, @Nullable final Window window) {
notNull("path", path);
notNull("expression", expression);
return simpleParameterWindowFunction(path, "$max", expression, window);
}
/**
* Builds a computation of the number of documents in the {@code window}.
*
* @param path The output field path.
* @param window The window.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-count $count
*/
public static WindowedComputation count(final String path, @Nullable final Window window) {
notNull("path", path);
return simpleParameterWindowFunction(path, "$count", null, window);
}
/**
* Builds a computation of the time derivative by subtracting the evaluation result of the {@code expression} against the last document
* and the first document in the {@code window} and dividing it by the difference in the values of the
* {@link Aggregates#setWindowFields(Object, Bson, List) sortBy} field of the respective documents.
* Other documents in the {@code window} have no effect on the computation.
*
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) Sorting} is required.
*
* @param path The output field path.
* @param expression The expression.
* @param window The window.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-derivative $derivative
*/
public static WindowedComputation derivative(final String path, final TExpression expression,
final Window window) {
notNull("path", path);
notNull("expression", expression);
notNull("window", window);
final Map args = new HashMap<>(1);
args.put(ParamName.INPUT, expression);
return compoundParameterWindowFunction(path, "$derivative", args, window);
}
/**
* Builds a computation of the time derivative by subtracting the evaluation result of the {@code expression} against the last document
* and the first document in the {@code window} and dividing it by the difference in the BSON {@link BsonType#DATE_TIME Date}
* values of the {@link Aggregates#setWindowFields(Object, Bson, List) sortBy} field of the respective documents.
* Other documents in the {@code window} have no effect on the computation.
*
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) Sorting} is required.
*
* @param path The output field path.
* @param expression The expression.
* @param window The window.
* @param unit The desired time unit for the divisor. Allowed values are:
* {@link MongoTimeUnit#WEEK}, {@link MongoTimeUnit#DAY}, {@link MongoTimeUnit#HOUR}, {@link MongoTimeUnit#MINUTE},
* {@link MongoTimeUnit#SECOND}, {@link MongoTimeUnit#MILLISECOND}.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-derivative $derivative
*/
public static WindowedComputation timeDerivative(final String path, final TExpression expression, final Window window,
final MongoTimeUnit unit) {
notNull("path", path);
notNull("expression", expression);
notNull("window", window);
notNull("unit", unit);
isTrueArgument("unit must be either of WEEK, DAY, HOUR, MINUTE, SECOND, MILLISECOND", unit.fixed());
final Map args = new LinkedHashMap<>(2);
args.put(ParamName.INPUT, expression);
args.put(ParamName.UNIT, unit.value());
return compoundParameterWindowFunction(path, "$derivative", args, window);
}
/**
* Builds a computation of the approximate integral of a function that maps values of
* the {@link Aggregates#setWindowFields(Object, Bson, List) sortBy} field to evaluation results of the {@code expression}
* against the same document. The limits of integration match the {@code window} bounds.
* The approximation is done by using the
*
* trapezoidal rule.
*
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) Sorting} is required.
*
* @param path The output field path.
* @param expression The expression.
* @param window The window.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-integral $integral
*/
public static WindowedComputation integral(final String path, final TExpression expression, final Window window) {
notNull("path", path);
notNull("expression", expression);
notNull("window", window);
final Map args = new HashMap<>(1);
args.put(ParamName.INPUT, expression);
return compoundParameterWindowFunction(path, "$integral", args, window);
}
/**
* Builds a computation of the approximate integral of a function that maps BSON {@link BsonType#DATE_TIME Date} values of
* the {@link Aggregates#setWindowFields(Object, Bson, List) sortBy} field to evaluation results of the {@code expression}
* against the same document. The limits of integration match the {@code window} bounds.
* The approximation is done by using the trapezoidal rule.
*
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) Sorting} is required.
*
* @param path The output field path.
* @param expression The expression.
* @param window The window.
* @param unit The desired time unit for the divisor. Allowed values are:
* {@link MongoTimeUnit#WEEK}, {@link MongoTimeUnit#DAY}, {@link MongoTimeUnit#HOUR}, {@link MongoTimeUnit#MINUTE},
* {@link MongoTimeUnit#SECOND}, {@link MongoTimeUnit#MILLISECOND}.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-integral $integral
*/
public static WindowedComputation timeIntegral(final String path, final TExpression expression, final Window window,
final MongoTimeUnit unit) {
notNull("path", path);
notNull("expression", expression);
notNull("window", window);
notNull("unit", unit);
isTrueArgument("unit must be either of WEEK, DAY, HOUR, MINUTE, SECOND, MILLISECOND", unit.fixed());
final Map args = new LinkedHashMap<>(2);
args.put(ParamName.INPUT, expression);
args.put(ParamName.UNIT, unit.value());
return compoundParameterWindowFunction(path, "$integral", args, window);
}
/**
* Builds a computation of the sample covariance between the evaluation results of the two expressions over the {@code window}.
*
*
* @param path The output field path.
* @param expression1 The first expression.
* @param expression2 The second expression.
* @param window The window.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-covariance-samp $covarianceSamp
*/
public static WindowedComputation covarianceSamp(final String path, final TExpression expression1,
final TExpression expression2, @Nullable final Window window) {
notNull("path", path);
notNull("expression1", expression1);
notNull("expression2", expression2);
List expressions = new ArrayList<>(2);
expressions.add(expression1);
expressions.add(expression2);
return simpleParameterWindowFunction(path, "$covarianceSamp", expressions, window);
}
/**
* Builds a computation of the population covariance between the evaluation results of the two expressions over the {@code window}.
*
* @param path The output field path.
* @param expression1 The first expression.
* @param expression2 The second expression.
* @param window The window.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-covariance-pop $covariancePop
*/
public static WindowedComputation covariancePop(final String path, final TExpression expression1,
final TExpression expression2, @Nullable final Window window) {
notNull("path", path);
notNull("expression1", expression1);
notNull("expression2", expression2);
List expressions = new ArrayList<>(2);
expressions.add(expression1);
expressions.add(expression2);
return simpleParameterWindowFunction(path, "$covariancePop", expressions, window);
}
/**
* Builds a computation of the exponential moving average of the evaluation results of the {@code expression} over a window
* that includes {@code n} - 1 documents preceding the current document and the current document, with more weight on documents
* closer to the current one.
*
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) Sorting} is required.
*
* @param path The output field path.
* @param expression The expression.
* @param n Must be positive.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-exp-moving-avg $expMovingAvg
*/
public static WindowedComputation expMovingAvg(final String path, final TExpression expression, final int n) {
notNull("path", path);
notNull("expression", expression);
isTrueArgument("n > 0", n > 0);
final Map args = new LinkedHashMap<>(2);
args.put(ParamName.INPUT, expression);
args.put(ParamName.N, n);
return compoundParameterWindowFunction(path, "$expMovingAvg", args, null);
}
/**
* Builds a computation of the exponential moving average of the evaluation results of the {@code expression} over the half-bounded
* window [{@link Bound#UNBOUNDED}, {@link Bound#CURRENT}], with {@code alpha} representing the degree of weighting decrease.
*
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) Sorting} is required.
*
* @param path The output field path.
* @param expression The expression.
* @param alpha A parameter specifying how fast weighting decrease happens. A higher {@code alpha} discounts older observations faster.
* Must belong to the interval (0, 1).
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-exp-moving-avg $expMovingAvg
*/
public static WindowedComputation expMovingAvg(final String path, final TExpression expression, final double alpha) {
notNull("path", path);
notNull("expression", expression);
isTrueArgument("alpha > 0", alpha > 0);
isTrueArgument("alpha < 1", alpha < 1);
final Map args = new LinkedHashMap<>(2);
args.put(ParamName.INPUT, expression);
args.put(ParamName.ALPHA, alpha);
return compoundParameterWindowFunction(path, "$expMovingAvg", args, null);
}
/**
* Builds a computation that adds the evaluation results of the {@code expression} over the {@code window}
* to a BSON {@link org.bson.BsonType#ARRAY Array}.
* Order within the array is guaranteed if {@link Aggregates#setWindowFields(Object, Bson, List) sortBy} is specified.
*
* @param path The output field path.
* @param expression The expression.
* @param window The window.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-push $push
*/
public static WindowedComputation push(final String path, final TExpression expression, @Nullable final Window window) {
notNull("path", path);
notNull("expression", expression);
return simpleParameterWindowFunction(path, "$push", expression, window);
}
/**
* Builds a computation that adds the evaluation results of the {@code expression} over the {@code window}
* to a BSON {@link org.bson.BsonType#ARRAY Array} and excludes duplicates.
* Order within the array is not specified.
*
* @param path The output field path.
* @param expression The expression.
* @param window The window.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-add-to-set $addToSet
*/
public static WindowedComputation addToSet(final String path, final TExpression expression,
@Nullable final Window window) {
notNull("path", path);
notNull("expression", expression);
return simpleParameterWindowFunction(path, "$addToSet", expression, window);
}
/**
* Builds a computation of the evaluation result of the {@code expression} against the first document in the {@code window}.
*
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) Sorting} is required.
*
* @param path The output field path.
* @param expression The expression.
* @param window The window.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-first $first
*/
public static WindowedComputation first(final String path, final TExpression expression, @Nullable final Window window) {
notNull("path", path);
notNull("expression", expression);
return simpleParameterWindowFunction(path, "$first", expression, window);
}
/**
* Builds a computation of the evaluation result of the {@code expression} against the last document in the {@code window}.
*
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) Sorting} is required.
*
* @param path The output field path.
* @param expression The expression.
* @param window The window.
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-last $last
*/
public static WindowedComputation last(final String path, final TExpression expression, @Nullable final Window window) {
notNull("path", path);
notNull("expression", expression);
return simpleParameterWindowFunction(path, "$last", expression, window);
}
/**
* Builds a computation of the evaluation result of the {@code expression} for the document whose position is shifted by the given
* amount relative to the current document. If the shifted document is outside of the
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) partition} containing the current document,
* then the {@code defaultExpression} is used instead of the {@code expression}.
*
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) Sorting} is required.
*
* @param path The output field path.
* @param expression The expression.
* @param defaultExpression The default expression.
* If {@code null}, then the default expression is evaluated to BSON {@link org.bson.BsonNull null}.
* Must evaluate to a constant value.
* @param by The shift specified similarly to {@linkplain Windows rules for window bounds}:
*
* - 0 means the current document;
* - a negative value refers to the document preceding the current one;
* - a positive value refers to the document following the current one.
*
* @param The expression type.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-shift $shift
*/
public static WindowedComputation shift(final String path, final TExpression expression,
@Nullable final TExpression defaultExpression, final int by) {
notNull("path", path);
notNull("expression", expression);
final Map args = new LinkedHashMap<>(3);
args.put(ParamName.OUTPUT, expression);
args.put(ParamName.BY, by);
if (defaultExpression != null) {
args.put(ParamName.DEFAULT, defaultExpression);
}
return compoundParameterWindowFunction(path, "$shift", args, null);
}
/**
* Builds a computation of the order number of each document in its
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) partition}.
*
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) Sorting} is required.
*
* @param path The output field path.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-document-number $documentNumber
*/
public static WindowedComputation documentNumber(final String path) {
notNull("path", path);
return simpleParameterWindowFunction(path, "$documentNumber", null, null);
}
/**
* Builds a computation of the rank of each document in its
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) partition}.
* Documents with the same value(s) of the {@linkplain Aggregates#setWindowFields(Object, Bson, List) sortBy} fields result in
* the same ranking and result in gaps in the returned ranks.
* For example, a partition with the sequence [1, 3, 3, 5] representing the values of the single {@code sortBy} field
* produces the following sequence of rank values: [1, 2, 2, 4].
*
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) Sorting} is required.
*
* @param path The output field path.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-rank $rank
*/
public static WindowedComputation rank(final String path) {
notNull("path", path);
return simpleParameterWindowFunction(path, "$rank", null, null);
}
/**
* Builds a computation of the dense rank of each document in its
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) partition}.
* Documents with the same value(s) of the {@linkplain Aggregates#setWindowFields(Object, Bson, List) sortBy} fields result in
* the same ranking but do not result in gaps in the returned ranks.
* For example, a partition with the sequence [1, 3, 3, 5] representing the values of the single {@code sortBy} field
* produces the following sequence of rank values: [1, 2, 2, 3].
*
* {@linkplain Aggregates#setWindowFields(Object, Bson, List) Sorting} is required.
*
* @param path The output field path.
* @return The constructed windowed computation.
* @mongodb.driver.dochub core/window-functions-dense-rank $denseRank
*/
public static WindowedComputation denseRank(final String path) {
notNull("path", path);
return simpleParameterWindowFunction(path, "$denseRank", null, null);
}
private static WindowedComputation simpleParameterWindowFunction(final String path, final String functionName,
@Nullable final Object expression,
@Nullable final Window window) {
return new BsonFieldWindowedComputation(new BsonField(path,
new SimpleParameterFunctionAndWindow(functionName, expression, window)));
}
private static WindowedComputation compoundParameterWindowFunction(final String path, final String functionName,
final Map args,
@Nullable final Window window) {
return new BsonFieldWindowedComputation(new BsonField(path,
new CompoundParameterFunctionAndWindow(functionName, args, window)));
}
private WindowedComputations() {
throw new UnsupportedOperationException();
}
private static final class BsonFieldWindowedComputation implements WindowedComputation {
private final BsonField wrapped;
BsonFieldWindowedComputation(final BsonField field) {
wrapped = assertNotNull(field);
}
@Override
public BsonField toBsonField() {
return wrapped;
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final BsonFieldWindowedComputation that = (BsonFieldWindowedComputation) o;
return wrapped.equals(that.wrapped);
}
@Override
public int hashCode() {
return wrapped.hashCode();
}
@Override
public String toString() {
return wrapped.toString();
}
}
/**
* A combination of a window function and its window.
*/
private abstract static class AbstractFunctionAndWindow implements Bson {
private final String functionName;
@Nullable
private final Window window;
AbstractFunctionAndWindow(final String functionName, @Nullable final Window window) {
this.functionName = functionName;
this.window = window;
}
final void writeWindow(final CodecRegistry codecRegistry, final BsonDocumentWriter writer) {
if (window != null) {
writer.writeName("window");
BuildersHelper.encodeValue(writer, window, codecRegistry);
}
}
final String functionName() {
return functionName;
}
final Optional window() {
return Optional.ofNullable(window);
}
}
private static final class SimpleParameterFunctionAndWindow extends AbstractFunctionAndWindow {
@Nullable
private final Object expression;
SimpleParameterFunctionAndWindow(final String functionName, @Nullable final Object expression, @Nullable final Window window) {
super(functionName, window);
this.expression = expression;
}
@Override
public BsonDocument toBsonDocument(final Class tDocumentClass, final CodecRegistry codecRegistry) {
BsonDocumentWriter writer = new BsonDocumentWriter(new BsonDocument());
writer.writeStartDocument();
writer.writeName(functionName());
if (expression == null) {
writer.writeStartDocument();
writer.writeEndDocument();
} else {
BuildersHelper.encodeValue(writer, expression, codecRegistry);
}
writeWindow(codecRegistry, writer);
writer.writeEndDocument();
return writer.getDocument();
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final SimpleParameterFunctionAndWindow that = (SimpleParameterFunctionAndWindow) o;
return functionName().equals(that.functionName()) && Objects.equals(expression, that.expression)
&& window().equals(that.window());
}
@Override
public int hashCode() {
return Objects.hash(functionName(), expression, window());
}
@Override
public String toString() {
return "WindowFunction{"
+ "name='" + functionName() + '\''
+ ", expression=" + expression
+ ", window=" + window()
+ '}';
}
}
private static final class CompoundParameterFunctionAndWindow extends AbstractFunctionAndWindow {
private final Map args;
CompoundParameterFunctionAndWindow(final String functionName, final Map args,
@Nullable final Window window) {
super(functionName, window);
this.args = args;
}
@Override
public BsonDocument toBsonDocument(final Class tDocumentClass, final CodecRegistry codecRegistry) {
BsonDocumentWriter writer = new BsonDocumentWriter(new BsonDocument());
writer.writeStartDocument();
writer.writeName(functionName());
writer.writeStartDocument();
args.forEach((paramName, paramValue) -> {
writer.writeName(paramName.value());
BuildersHelper.encodeValue(writer, paramValue, codecRegistry);
});
writer.writeEndDocument();
writeWindow(codecRegistry, writer);
writer.writeEndDocument();
return writer.getDocument();
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final CompoundParameterFunctionAndWindow that = (CompoundParameterFunctionAndWindow) o;
return functionName().equals(that.functionName()) && Objects.equals(args, that.args) && window().equals(that.window());
}
@Override
public int hashCode() {
return Objects.hash(functionName(), args, window());
}
@Override
public String toString() {
return "WindowFunction{"
+ "name='" + functionName() + '\''
+ ", args=" + args
+ ", window=" + window()
+ '}';
}
}
private enum ParamName {
INPUT("input"),
UNIT("unit"),
N("N"),
ALPHA("alpha"),
OUTPUT("output"),
BY("by"),
DEFAULT("default");
private final String value;
ParamName(final String value) {
this.value = value;
}
String value() {
return value;
}
}
}