blob: c0a4a7593f5bd06f744ae2b20f550448be029f76 [file] [edit]
// Copyright 2026 Google LLC
//
// 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 firestore
import (
"fmt"
pb "cloud.google.com/go/firestore/apiv1/firestorepb"
"google.golang.org/genproto/googleapis/type/latlng"
)
// FunctionExpression represents Firestore [Pipeline] functions, which can be evaluated within pipeline
// execution.
type FunctionExpression interface {
Expression
isFunction()
}
type baseFunction struct {
*baseExpression
}
func (b *baseFunction) isFunction() {}
// Ensure that *baseFunction implements the FunctionExpression interface.
var _ FunctionExpression = (*baseFunction)(nil)
func newBaseFunction(name string, params []Expression) *baseFunction {
argsPbVals := make([]*pb.Value, 0, len(params))
for i, param := range params {
paramExpr := asFieldExpr(param)
pbVal, err := paramExpr.toProto()
if err != nil {
return &baseFunction{baseExpression: &baseExpression{err: fmt.Errorf("firestore: error converting arg %d for function %q: %w", i, name, err)}}
}
argsPbVals = append(argsPbVals, pbVal)
}
pbVal := &pb.Value{ValueType: &pb.Value_FunctionValue{
FunctionValue: &pb.Function{
Name: name,
Args: argsPbVals,
},
}}
return &baseFunction{baseExpression: &baseExpression{pbVal: pbVal}}
}
func newBaseFunctionFromBooleans(name string, params []BooleanExpression) *baseFunction {
exprs := make([]Expression, len(params))
for i, p := range params {
exprs[i] = p
}
return newBaseFunction(name, exprs)
}
// Add creates an expression that adds two expressions together, returning it as an Expr.
// - left can be a field path string, [FieldPath] or [Expression].
// - right can be a numeric constant or a numeric [Expression].
func Add(left, right any) Expression {
return leftNumericRightToBaseFunction("add", left, right)
}
// Subtract creates an expression that subtracts the right expression from the left expression, returning it as an Expr.
// - left can be a field path string, [FieldPath] or [Expression].
// - right can be a numeric constant or a numeric [Expression].
func Subtract(left, right any) Expression {
return leftNumericRightToBaseFunction("subtract", left, right)
}
// Multiply creates an expression that multiplies the left and right expressions, returning it as an Expr.
// - left can be a field path string, [FieldPath] or [Expression].
// - right can be a numeric constant or a numeric [Expression].
func Multiply(left, right any) Expression {
return leftNumericRightToBaseFunction("multiply", left, right)
}
// Divide creates an expression that divides the left expression by the right expression, returning it as an Expr.
// - left can be a field path string, [FieldPath] or [Expression].
// - right can be a numeric constant or a numeric [Expression].
func Divide(left, right any) Expression {
return leftNumericRightToBaseFunction("divide", left, right)
}
// Abs creates an expression that is the absolute value of the input field or expression.
// - numericExprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that returns a number when evaluated.
func Abs(numericExprOrFieldPath any) Expression {
return newBaseFunction("abs", []Expression{asFieldExpr(numericExprOrFieldPath)})
}
// Floor creates an expression that is the largest integer that isn't less than the input field or expression.
// - numericExprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that returns a number when evaluated.
func Floor(numericExprOrFieldPath any) Expression {
return newBaseFunction("floor", []Expression{asFieldExpr(numericExprOrFieldPath)})
}
// Ceil creates an expression that is the smallest integer that isn't less than the input field or expression.
// - numericExprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that returns a number when evaluated.
func Ceil(numericExprOrFieldPath any) Expression {
return newBaseFunction("ceil", []Expression{asFieldExpr(numericExprOrFieldPath)})
}
// Exp creates an expression that is the Euler's number e raised to the power of the input field or expression.
// - numericExprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that returns a number when evaluated.
func Exp(numericExprOrFieldPath any) Expression {
return newBaseFunction("exp", []Expression{asFieldExpr(numericExprOrFieldPath)})
}
// Log creates an expression that is logarithm of the left expression to base as the right expression, returning it as an Expr.
// - left can be a field path string, [FieldPath] or [Expression].
// - right can be a constant or an [Expression].
func Log(left, right any) Expression {
return leftNumericRightToBaseFunction("log", left, right)
}
// Log10 creates an expression that is the base 10 logarithm of the input field or expression.
// - numericExprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that returns a number when evaluated.
func Log10(numericExprOrFieldPath any) Expression {
return newBaseFunction("log10", []Expression{asFieldExpr(numericExprOrFieldPath)})
}
// Ln creates an expression that is the natural logarithm (base e) of the input field or expression.
// - numericExprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that returns a number when evaluated.
func Ln(numericExprOrFieldPath any) Expression {
return newBaseFunction("ln", []Expression{asFieldExpr(numericExprOrFieldPath)})
}
// Mod creates an expression that computes the modulo of the left expression by the right expression, returning it as an Expr.
// - left can be a field path string, [FieldPath] or [Expression].
// - right can be a numeric constant or a numeric [Expression].
func Mod(left, right any) Expression {
return leftNumericRightToBaseFunction("mod", left, right)
}
// Pow creates an expression that computes the left expression raised to the power of the right expression, returning it as an Expr.
// - left can be a field path string, [FieldPath] or [Expression].
// - right can be a numeric constant or a numeric [Expression].
func Pow(left, right any) Expression {
return leftNumericRightToBaseFunction("pow", left, right)
}
// Round creates an expression that rounds the input field or expression to nearest integer.
// - numericExprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that returns a number when evaluated.
func Round(numericExprOrFieldPath any) Expression {
return newBaseFunction("round", []Expression{asFieldExpr(numericExprOrFieldPath)})
}
// RoundToPrecision creates an expression that rounds a number to a specified number of decimal places.
// If places is positive, rounds off digits to the right of the decimal point.
// If places is negative, rounds off digits to the left of the decimal point.
// - numericExprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that returns a number when evaluated.
// - places can be an int, int32, int64 or [Expression].
func RoundToPrecision(numericExprOrFieldPath any, places any) Expression {
return newBaseFunction("round", []Expression{asFieldExpr(numericExprOrFieldPath), asInt64Expr(places)})
}
// Trunc creates an expression that truncates a number to an integer.
// - numericExprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that returns a number when evaluated.
func Trunc(numericExprOrFieldPath any) Expression {
return newBaseFunction("trunc", []Expression{asFieldExpr(numericExprOrFieldPath)})
}
// TruncToPrecision creates an expression that truncates a number to a specified number of decimal places.
// - numericExprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that returns a number when evaluated.
// - places can be an int, int32, int64 or [Expression].
func TruncToPrecision(numericExprOrFieldPath any, places any) Expression {
return newBaseFunction("trunc", []Expression{asFieldExpr(numericExprOrFieldPath), asInt64Expr(places)})
}
// Sqrt creates an expression that is the square root of the input field or expression.
// - numericExprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that returns a number when evaluated.
func Sqrt(numericExprOrFieldPath any) Expression {
return newBaseFunction("sqrt", []Expression{asFieldExpr(numericExprOrFieldPath)})
}
// Cmp creates an expression that compares the left and right expressions, returning it as an Expr.
// Returns -1 if left < right, 0 if left == right, and 1 if left > right.
// - left can be a field path string, [FieldPath] or [Expression].
// - right can be a constant or an [Expression].
func Cmp(left, right any) Expression {
return leftRightToBaseFunction("cmp", left, right)
}
// TimestampAdd creates an expression that adds a specified amount of time to a timestamp.
// - timestamp can be a field path string, [FieldPath] or [Expression].
// - unit can be a string or an [Expression]. Valid units include "microsecond", "millisecond", "second", "minute", "hour" and "day".
// - amount can be an int, int32, int64 or [Expression].
func TimestampAdd(timestamp, unit, amount any) Expression {
return newBaseFunction("timestamp_add", []Expression{asFieldExpr(timestamp), validateTimestampUnit(unit), asInt64Expr(amount)})
}
// TimestampSubtract creates an expression that subtracts a specified amount of time from a timestamp.
// - timestamp can be a field path string, [FieldPath] or [Expression].
// - unit can be a string or an [Expression]. Valid units include "microsecond", "millisecond", "second", "minute", "hour" and "day".
// - amount can be an int, int32, int64 or [Expression].
func TimestampSubtract(timestamp, unit, amount any) Expression {
return newBaseFunction("timestamp_subtract", []Expression{asFieldExpr(timestamp), validateTimestampUnit(unit), asInt64Expr(amount)})
}
// TimestampExtract creates an expression that extracts a part from a timestamp.
// - timestamp can be a field path string, [FieldPath] or [Expression].
// - part can be a string or an [Expression]. Valid parts include "microsecond", "millisecond", "second", "minute", "hour", "day",
// "dayofweek", "dayofyear", "week", "week(monday)", "week(tuesday)", "week(wednesday)", "week(thursday)",
// "week(friday)", "week(saturday)", "week(sunday)", "month", "quarter", "year", "isoweek", and "isoyear".
func TimestampExtract(timestamp, part any) Expression {
return newBaseFunction("timestamp_extract", []Expression{asFieldExpr(timestamp), validateTimestampPart(part)})
}
// TimestampExtractWithTimezone creates an expression that extracts a part from a timestamp in a given timezone.
// - timestamp can be a field path string, [FieldPath] or [Expression].
// - part can be a string or an [Expression]. Valid parts include "microsecond", "millisecond", "second", "minute", "hour", "day",
// "dayofweek", "dayofyear", "week", "week(monday)", "week(tuesday)", "week(wednesday)", "week(thursday)",
// "week(friday)", "week(saturday)", "week(sunday)", "month", "quarter", "year", "isoweek", and "isoyear".
// - timezone can be a string or an [Expression].
func TimestampExtractWithTimezone(timestamp, part, timezone any) Expression {
return newBaseFunction("timestamp_extract", []Expression{asFieldExpr(timestamp), validateTimestampPart(part), asStringExpr(timezone)})
}
// TimestampDiff creates an expression that calculates the difference between two timestamps.
// - end can be a field path string, [FieldPath] or [Expression].
// - start can be a field path string, [FieldPath] or [Expression].
// - unit can be a string or an [Expression]. Valid units include "microsecond", "millisecond", "second", "minute", "hour" and "day".
func TimestampDiff(end, start, unit any) Expression {
return newBaseFunction("timestamp_diff", []Expression{asFieldExpr(end), asFieldExpr(start), validateTimestampUnit(unit)})
}
// TimestampTruncate creates an expression that truncates a timestamp to a specified granularity.
// - timestamp can be a field path string, [FieldPath] or [Expression].
// - granularity can be a string or an [Expression]. Valid values are "microsecond",
// "millisecond", "second", "minute", "hour", "day", "week", "week(monday)", "week(tuesday)",
// "week(wednesday)", "week(thursday)", "week(friday)", "week(saturday)", "week(sunday)",
// "isoweek", "month", "quarter", "year", and "isoyear".
func TimestampTruncate(timestamp, granularity any) Expression {
return newBaseFunction("timestamp_trunc", []Expression{asFieldExpr(timestamp), validateTimestampGranularity(granularity)})
}
// TimestampTruncateWithTimezone creates an expression that truncates a timestamp to a specified granularity in a given timezone.
// - timestamp can be a field path string, [FieldPath] or [Expression].
// - granularity can be a string or an [Expression]. Valid values are "microsecond",
// "millisecond", "second", "minute", "hour", "day", "week", "week(monday)", "week(tuesday)",
// "week(wednesday)", "week(thursday)", "week(friday)", "week(saturday)", "week(sunday)",
// "isoweek", "month", "quarter", "year", and "isoyear".
// - timezone can be a string or an [Expression]. Valid values are from the TZ database
// (e.g., "America/Los_Angeles") or in the format "Etc/GMT-1".
func TimestampTruncateWithTimezone(timestamp, granularity any, timezone any) Expression {
return newBaseFunction("timestamp_trunc", []Expression{asFieldExpr(timestamp), validateTimestampGranularity(granularity), asStringExpr(timezone)})
}
// TimestampToUnixMicros creates an expression that converts a timestamp expression to the number of microseconds since
// the Unix epoch (1970-01-01 00:00:00 UTC).
// - timestamp can be a field path string, [FieldPath] or [Expression].
func TimestampToUnixMicros(timestamp any) Expression {
return newBaseFunction("timestamp_to_unix_micros", []Expression{asFieldExpr(timestamp)})
}
// TimestampToUnixMillis creates an expression that converts a timestamp expression to the number of milliseconds since
// the Unix epoch (1970-01-01 00:00:00 UTC).
// - timestamp can be a field path string, [FieldPath] or [Expression].
func TimestampToUnixMillis(timestamp any) Expression {
return newBaseFunction("timestamp_to_unix_millis", []Expression{asFieldExpr(timestamp)})
}
// TimestampToUnixSeconds creates an expression that converts a timestamp expression to the number of seconds since
// the Unix epoch (1970-01-01 00:00:00 UTC).
// - timestamp can be a field path string, [FieldPath] or [Expression].
func TimestampToUnixSeconds(timestamp any) Expression {
return newBaseFunction("timestamp_to_unix_seconds", []Expression{asFieldExpr(timestamp)})
}
// UnixMicrosToTimestamp creates an expression that converts a Unix timestamp in microseconds to a Firestore timestamp.
// - micros can be a field path string, [FieldPath] or [Expression].
func UnixMicrosToTimestamp(micros any) Expression {
return newBaseFunction("unix_micros_to_timestamp", []Expression{asFieldExpr(micros)})
}
// UnixMillisToTimestamp creates an expression that converts a Unix timestamp in milliseconds to a Firestore timestamp.
// - millis can be a field path string, [FieldPath] or [Expression].
func UnixMillisToTimestamp(millis any) Expression {
return newBaseFunction("unix_millis_to_timestamp", []Expression{asFieldExpr(millis)})
}
// UnixSecondsToTimestamp creates an expression that converts a Unix timestamp in seconds to a Firestore timestamp.
// - seconds can be a field path string, [FieldPath] or [Expression].
func UnixSecondsToTimestamp(seconds any) Expression {
return newBaseFunction("unix_seconds_to_timestamp", []Expression{asFieldExpr(seconds)})
}
// CurrentTimestamp creates an expression that returns the current timestamp.
func CurrentTimestamp() Expression {
return newBaseFunction("current_timestamp", []Expression{})
}
// CurrentDocument creates an expression that represents the current document being processed.
//
// This expression is useful when you need to access the entire document as a map, or pass the
// document itself to a function or subquery.
//
// Example:
//
// // Define the current document as a variable "doc"
// client.Pipeline().Collection("books").
// Define(AliasedExpressions(CurrentDocument().As("doc"))).
// // Access a field from the defined document variable
// Select(Fields(GetField(Variable("doc"), "title")))
func CurrentDocument() Expression {
return newBaseFunction("current_document", []Expression{})
}
// Variable creates an expression that retrieves the value of a variable bound via Define.
//
// Example:
//
// // Define a variable "discountedPrice" and use it in a filter
// client.Pipeline().Collection("products").
// Define(AliasedExpressions(Multiply("price", 0.9).As("discountedPrice"))).
// Where(LessThan(Variable("discountedPrice"), 100))
func Variable(name string) Expression {
pbVal := &pb.Value{ValueType: &pb.Value_VariableReferenceValue{VariableReferenceValue: name}}
return &baseExpression{pbVal: pbVal}
}
// ArrayLength creates an expression that calculates the length of an array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
func ArrayLength(exprOrFieldPath any) Expression {
return newBaseFunction("array_length", []Expression{asFieldExpr(exprOrFieldPath)})
}
// Array creates an expression that represents a Firestore array.
// - elements can be any number of values or expressions that will form the elements of the array.
func Array(elements ...any) Expression {
return newBaseFunction("array", toArrayOfExprOrConstant(elements))
}
// ArrayFromSlice creates a new array expression from a slice of elements.
// This function is necessary for creating an array from an existing typed slice (e.g., []int),
// as the [Array] function (which takes variadic arguments) cannot directly accept a typed slice
// using the spread operator (...). It handles the conversion of each element to `any` internally.
func ArrayFromSlice[T any](elements []T) Expression {
return newBaseFunction("array", toExprsFromSlice(elements))
}
// ArrayGet creates an expression that retrieves an element from an array at a specified index.
//
// This is a typed function. It expects the first argument to be an array. If the
// target is not an array, the query will fail with a type error.
// If the target is null, the result is null.
//
// For a version that returns an absent value (UNSET) instead of failing on type
// mismatch, use [Offset].
//
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - offset is the 0-based index of the element to retrieve. Supports negative indexing.
func ArrayGet(exprOrFieldPath any, offset any) Expression {
return newBaseFunction("array_get", []Expression{asFieldExpr(exprOrFieldPath), asInt64Expr(offset)})
}
// Offset creates an expression that accesses an element from an array at a specified index.
//
// This is a field access function. If the input is not an array, or if the index
// is out of bounds, it evaluates to an absent value.
//
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - index is the 0-based index of the element to retrieve. It can be an int or an [Expression].
// Supports negative indexing (e.g., -1 returns the last element).
func Offset(exprOrFieldPath any, index any) Expression {
return newBaseFunction("offset", []Expression{asFieldExpr(exprOrFieldPath), asInt64Expr(index)})
}
// ArrayReverse creates an expression that reverses the order of elements in an array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
func ArrayReverse(exprOrFieldPath any) Expression {
return newBaseFunction("array_reverse", []Expression{asFieldExpr(exprOrFieldPath)})
}
// ArrayConcat creates an expression that concatenates multiple arrays into a single array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - otherArrays are the other arrays to concatenate.
func ArrayConcat(exprOrFieldPath any, otherArrays ...any) Expression {
return newBaseFunction("array_concat", append([]Expression{asFieldExpr(exprOrFieldPath)}, toArrayOfExprOrConstant(otherArrays)...))
}
// ArraySum creates an expression that calculates the sum of all elements in a numeric array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a numeric array.
func ArraySum(exprOrFieldPath any) Expression {
return newBaseFunction("sum", []Expression{asFieldExpr(exprOrFieldPath)})
}
// ArrayMaximum creates an expression that finds the maximum element in a numeric array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a numeric array.
func ArrayMaximum(exprOrFieldPath any) Expression {
return newBaseFunction("maximum", []Expression{asFieldExpr(exprOrFieldPath)})
}
// ArrayMinimum creates an expression that finds the minimum element in a numeric array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a numeric array.
func ArrayMinimum(exprOrFieldPath any) Expression {
return newBaseFunction("minimum", []Expression{asFieldExpr(exprOrFieldPath)})
}
// ArrayMaximumN creates an expression that finds the N maximum elements in an array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - n can be an int, int32, int64 or [Expression].
func ArrayMaximumN(exprOrFieldPath any, n any) Expression {
return newBaseFunction("maximum_n", []Expression{asFieldExpr(exprOrFieldPath), asInt64Expr(n)})
}
// ArrayMinimumN creates an expression that finds the N minimum elements in an array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - n can be an int, int32, int64 or [Expression].
func ArrayMinimumN(exprOrFieldPath any, n any) Expression {
return newBaseFunction("minimum_n", []Expression{asFieldExpr(exprOrFieldPath), asInt64Expr(n)})
}
// ArrayFirst creates an expression that returns the first element of an array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
func ArrayFirst(exprOrFieldPath any) Expression {
return newBaseFunction("array_first", []Expression{asFieldExpr(exprOrFieldPath)})
}
// ArrayFirstN creates an expression that returns the first N elements of an array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - n can be an int, int32, int64 or [Expression].
func ArrayFirstN(exprOrFieldPath any, n any) Expression {
return newBaseFunction("array_first_n", []Expression{asFieldExpr(exprOrFieldPath), asInt64Expr(n)})
}
// ArrayLast creates an expression that returns the last element of an array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
func ArrayLast(exprOrFieldPath any) Expression {
return newBaseFunction("array_last", []Expression{asFieldExpr(exprOrFieldPath)})
}
// ArrayLastN creates an expression that returns the last N elements of an array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - n can be an int, int32, int64 or [Expression].
func ArrayLastN(exprOrFieldPath any, n any) Expression {
return newBaseFunction("array_last_n", []Expression{asFieldExpr(exprOrFieldPath), asInt64Expr(n)})
}
// ArraySliceToEnd creates an expression that returns a slice of an array starting from the specified offset.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - offset is the 0-based index of the first element to include. It can be an int, int32, int64 or [Expression].
func ArraySliceToEnd(exprOrFieldPath any, offset any) Expression {
return newBaseFunction("array_slice", []Expression{asFieldExpr(exprOrFieldPath), asInt64Expr(offset)})
}
// ArraySlice creates an expression that returns a slice of an array starting from the specified offset with a given length.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - offset is the 0-based index of the first element to include. It can be an int, int32, int64 or [Expression].
// - length is the number of elements to include. It can be an int, int32, int64 or [Expression].
func ArraySlice(exprOrFieldPath any, offset any, length any) Expression {
return newBaseFunction("array_slice", []Expression{asFieldExpr(exprOrFieldPath), asInt64Expr(offset), asInt64Expr(length)})
}
// ReferenceSliceToEnd creates an expression that returns a subset of segments from a document reference.
// - exprOrField can be a field path string, [FieldPath] or an [Expression] that evaluates to a document reference.
// - offset is the 0-based index of the first segment to include. It can be an int, int32, int64 or [Expression].
func ReferenceSliceToEnd(exprOrFieldPath any, offset any) Expression {
return newBaseFunction("reference_slice", []Expression{asFieldExpr(exprOrFieldPath), asInt64Expr(offset)})
}
// ReferenceSlice creates an expression that returns a subset of segments from a document reference with a given length.
// - exprOrField can be a field path string, [FieldPath] or an [Expression] that evaluates to a document reference.
// - offset is the 0-based index of the first segment to include. It can be an int, int32, int64 or [Expression].
// - length is the number of segments to include. It can be an int, int32, int64 or [Expression].
func ReferenceSlice(exprOrFieldPath any, offset any, length any) Expression {
return newBaseFunction("reference_slice", []Expression{asFieldExpr(exprOrFieldPath), asInt64Expr(offset), asInt64Expr(length)})
}
// ArrayFilter creates an expression for array_filter(array, param, body).
// - array can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - param is the name of the parameter to use in the body expression.
// - body is the expression to evaluate for each element of the array.
func ArrayFilter(array any, param string, body BooleanExpression) Expression {
return newBaseFunction("array_filter", []Expression{asFieldExpr(array), ConstantOf(param), body})
}
// ArrayTransform applies a transformation to each element of an array.
// - array can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - param is the name of the parameter to use in the transform expression.
// - body is the expression to evaluate for each element of the array.
func ArrayTransform(array any, param string, body Expression) Expression {
return newBaseFunction("array_transform", []Expression{asFieldExpr(array), ConstantOf(param), body})
}
// ArrayTransformWithIndex applies a transformation to each element of an array, providing the index.
// - array can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - param is the name of the parameter to use in the transform expression for the element.
// - indexParam is the name of the parameter to use in the transform expression for the index.
// - body is the expression to evaluate for each element of the array.
func ArrayTransformWithIndex(array any, param, indexParam string, body Expression) Expression {
return newBaseFunction("array_transform", []Expression{asFieldExpr(array), ConstantOf(param), ConstantOf(indexParam), body})
}
// ArrayIndexOf creates an expression that returns the first index of a search value in an array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - search is the value to search for. It can be a constant or [Expression].
func ArrayIndexOf(exprOrFieldPath any, search any) Expression {
return newBaseFunction("array_index_of", []Expression{asFieldExpr(exprOrFieldPath), toExprOrConstant(search), toExprOrConstant("first")})
}
// ArrayLastIndexOf creates an expression that returns the last index of a search value in an array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - search is the value to search for. It can be a constant or [Expression].
func ArrayLastIndexOf(exprOrFieldPath any, search any) Expression {
return newBaseFunction("array_index_of", []Expression{asFieldExpr(exprOrFieldPath), toExprOrConstant(search), toExprOrConstant("last")})
}
// ArrayIndexOfAll creates an expression that returns the indices of all occurrences of a search value in an array.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to an array.
// - search is the value to search for. It can be a constant or [Expression].
func ArrayIndexOfAll(exprOrFieldPath any, search any) Expression {
return newBaseFunction("array_index_of_all", []Expression{asFieldExpr(exprOrFieldPath), toExprOrConstant(search)})
}
// StorageSize creates an expression that calculates the storage size of a field or [Expression] in bytes.
// - exprOrFieldPath can be a field path string, [FieldPath] or [Expression].
func StorageSize(exprOrFieldPath any) Expression {
return newBaseFunction("storage_size", []Expression{asFieldExpr(exprOrFieldPath)})
}
// ByteLength creates an expression that calculates the length of a string represented by a field or [Expression] in UTF-8
// bytes.
// - exprOrFieldPath can be a field path string, [FieldPath] or [Expression].
func ByteLength(exprOrFieldPath any) Expression {
return newBaseFunction("byte_length", []Expression{asFieldExpr(exprOrFieldPath)})
}
// CharLength creates an expression that calculates the character length of a string field or expression in UTF8.
// - exprOrFieldPath can be a field path string, [FieldPath] or [Expression].
func CharLength(exprOrFieldPath any) Expression {
return newBaseFunction("char_length", []Expression{asFieldExpr(exprOrFieldPath)})
}
// StringConcat creates an expression that concatenates multiple strings into a single string.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
// - otherStrings are optional additional string expressions or string constants to concatenate.
func StringConcat(exprOrFieldPath any, otherStrings ...any) Expression {
args := make([]Expression, 1+len(otherStrings))
args[0] = asFieldExpr(exprOrFieldPath)
for i, v := range otherStrings {
args[i+1] = asStringExpr(v)
}
return newBaseFunction("string_concat", args)
}
// StringRepeat creates an expression that repeats a string a specified number of times.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
// - repetition is the number of times to repeat the string. It can be an int, int32, int64 or [Expression].
func StringRepeat(exprOrFieldPath any, repetition any) Expression {
return newBaseFunction("string_repeat", []Expression{asFieldExpr(exprOrFieldPath), asInt64Expr(repetition)})
}
// StringReplaceOne creates an expression that replaces the first occurrence of a search value with a replacement value.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
// - search is the value to search for. It can be a string or [Expression].
// - replacement is the value to replace with. It can be a string or [Expression].
func StringReplaceOne(exprOrFieldPath any, search, replacement any) Expression {
return newBaseFunction("string_replace_one", []Expression{asFieldExpr(exprOrFieldPath), asStringExpr(search), asStringExpr(replacement)})
}
// StringReplaceAll creates an expression that replaces all occurrences of a search value with a replacement value.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
// - search is the value to search for. It can be a string or [Expression].
// - replacement is the value to replace with. It can be a string or [Expression].
func StringReplaceAll(exprOrFieldPath any, search, replacement any) Expression {
return newBaseFunction("string_replace_all", []Expression{asFieldExpr(exprOrFieldPath), asStringExpr(search), asStringExpr(replacement)})
}
// StringReverse creates an expression that reverses a string.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
func StringReverse(exprOrFieldPath any) Expression {
return newBaseFunction("string_reverse", []Expression{asFieldExpr(exprOrFieldPath)})
}
// StringIndexOf creates an expression that returns the index of a search value in a string.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
// - search is the value to search for. It can be a string or [Expression].
func StringIndexOf(exprOrFieldPath any, search any) Expression {
return newBaseFunction("string_index_of", []Expression{asFieldExpr(exprOrFieldPath), asStringExpr(search)})
}
// Join creates an expression that joins the elements of a string array into a single string.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string array.
// - delimiter is the string to use as a separator between elements.
func Join(exprOrFieldPath any, delimiter any) Expression {
return newBaseFunction("join", []Expression{asFieldExpr(exprOrFieldPath), asStringExpr(delimiter)})
}
// Substring creates an expression that returns a substring of a string.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
// - index is the starting index of the substring.
// - length is the length of the substring.
func Substring(exprOrFieldPath any, index any, length any) Expression {
return newBaseFunction("substring", []Expression{asFieldExpr(exprOrFieldPath), asInt64Expr(index), asInt64Expr(length)})
}
// ToLower creates an expression that converts a string to lowercase.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
func ToLower(exprOrFieldPath any) Expression {
return newBaseFunction("to_lower", []Expression{asFieldExpr(exprOrFieldPath)})
}
// ToUpper creates an expression that converts a string to uppercase.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
func ToUpper(exprOrFieldPath any) Expression {
return newBaseFunction("to_upper", []Expression{asFieldExpr(exprOrFieldPath)})
}
// Trim creates an expression that removes leading and trailing whitespace from a string.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
func Trim(exprOrFieldPath any) Expression {
return newBaseFunction("trim", []Expression{asFieldExpr(exprOrFieldPath)})
}
// TrimValue creates an expression that removes specified characters from the beginning and end of a string.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
// - charsOrExprToTrim is a string or [Expression] specifying characters to remove.
func TrimValue(exprOrFieldPath any, charsOrExprToTrim any) Expression {
return newBaseFunction("trim", []Expression{asFieldExpr(exprOrFieldPath), asStringExpr(charsOrExprToTrim)})
}
// LTrim creates an expression that removes leading whitespace from a string.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
func LTrim(exprOrFieldPath any) Expression {
return newBaseFunction("ltrim", []Expression{asFieldExpr(exprOrFieldPath)})
}
// LTrimValue creates an expression that removes leading whitespace or specified characters from a string.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
// - charsOrExprToTrim is a string or [Expression] specifying characters to remove.
func LTrimValue(exprOrFieldPath any, charsOrExprToTrim any) Expression {
return newBaseFunction("ltrim", []Expression{asFieldExpr(exprOrFieldPath), asStringExpr(charsOrExprToTrim)})
}
// RTrim creates an expression that removes trailing whitespace from a string.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
func RTrim(exprOrFieldPath any) Expression {
return newBaseFunction("rtrim", []Expression{asFieldExpr(exprOrFieldPath)})
}
// RTrimValue creates an expression that removes trailing whitespace or specified characters from a string.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
// - charsOrExprToTrim is a string or [Expression] specifying characters to remove.
func RTrimValue(exprOrFieldPath any, charsOrExprToTrim any) Expression {
return newBaseFunction("rtrim", []Expression{asFieldExpr(exprOrFieldPath), asStringExpr(charsOrExprToTrim)})
}
// Split creates an expression that splits a string by a delimiter.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression] that evaluates to a string.
// - delimiter is the string to use to split by.
func Split(exprOrFieldPath any, delimiter any) Expression {
return newBaseFunction("split", []Expression{asFieldExpr(exprOrFieldPath), asStringExpr(delimiter)})
}
// Type creates an expression that returns the type of the expression.
// - exprOrFieldPath can be a field path string, [FieldPath] or an [Expression].
func Type(exprOrFieldPath any) Expression {
return newBaseFunction("type", []Expression{asFieldExpr(exprOrFieldPath)})
}
// CosineDistance creates an expression that calculates the cosine distance between two vectors.
// - vector1 can be a field path string, [FieldPath] or [Expression].
// - vector2 can be [Vector32], [Vector64], []float32, []float64 or [Expression].
func CosineDistance(vector1 any, vector2 any) Expression {
return newBaseFunction("cosine_distance", []Expression{asFieldExpr(vector1), asVectorExpr(vector2)})
}
// DotProduct creates an expression that calculates the dot product of two vectors.
// - vector1 can be a field path string, [FieldPath] or [Expression].
// - vector2 can be [Vector32], [Vector64], []float32, []float64 or [Expression].
func DotProduct(vector1 any, vector2 any) Expression {
return newBaseFunction("dot_product", []Expression{asFieldExpr(vector1), asVectorExpr(vector2)})
}
// EuclideanDistance creates an expression that calculates the euclidean distance between two vectors.
// - vector1 can be a field path string, [FieldPath] or [Expression].
// - vector2 can be [Vector32], [Vector64], []float32, []float64 or [Expression].
func EuclideanDistance(vector1 any, vector2 any) Expression {
return newBaseFunction("euclidean_distance", []Expression{asFieldExpr(vector1), asVectorExpr(vector2)})
}
// VectorLength creates an expression that calculates the length of a vector.
// - exprOrFieldPath can be a field path string, [FieldPath] or [Expression].
func VectorLength(exprOrFieldPath any) Expression {
return newBaseFunction("vector_length", []Expression{asFieldExpr(exprOrFieldPath)})
}
// Length creates an expression that calculates the length of string, array, map or vector.
// - exprOrField can be a field path string, [FieldPath] or an [Expression] that returns a string, array, map or vector when evaluated.
//
// Example:
//
// // Length of the 'name' field.
// Length("name")
func Length(exprOrField any) Expression {
return newBaseFunction("length", []Expression{asFieldExpr(exprOrField)})
}
// Reverse creates an expression that reverses a string, or array.
// - exprOrField can be a field path string, [FieldPath] or an [Expression] that returns a string, or array when evaluated.
//
// Example:
//
// // Reverse the 'name' field.
//
// Reverse("name")
func Reverse(exprOrField any) Expression {
return newBaseFunction("reverse", []Expression{asFieldExpr(exprOrField)})
}
// Concat creates an expression that concatenates expressions together.
// - exprOrField can be a field path string, [FieldPath] or an [Expression].
// - others can be a list of constants or [Expression].
//
// Example:
//
// // Concat the 'name' field with a constant string.
// Concat("name", "-suffix")
func Concat(exprOrField any, others ...any) Expression {
return newBaseFunction("concat", append([]Expression{asFieldExpr(exprOrField)}, toArrayOfExprOrConstant(others)...))
}
// GetCollectionID creates an expression that returns the ID of the collection that contains the document.
// - exprOrField can be a field path string, [FieldPath] or an [Expression] that evaluates to a field path.
func GetCollectionID(exprOrField any) Expression {
return newBaseFunction("collection_id", []Expression{asFieldExpr(exprOrField)})
}
// GetDocumentID creates an expression that returns the ID of the document.
// - exprStringOrDocRef can be a string, a [DocumentRef], or an [Expression] that evaluates to a document reference.
func GetDocumentID(exprStringOrDocRef any) Expression {
var expr Expression
switch v := exprStringOrDocRef.(type) {
case string:
expr = ConstantOf(v)
case *DocumentRef:
expr = ConstantOf(v)
case Expression:
expr = v
default:
return &baseFunction{baseExpression: &baseExpression{err: fmt.Errorf("firestore: value must be a string, DocumentRef, or Expr, but got %T", exprStringOrDocRef)}}
}
return newBaseFunction("document_id", []Expression{expr})
}
// GetParent creates an expression that returns the parent document of a document reference.
// - exprStringOrDocRef can be a string representation of the document path, a [DocumentRef], or an [Expression] that evaluates to a document path.
func GetParent(exprStringOrDocRef any) Expression {
var expr Expression
switch v := exprStringOrDocRef.(type) {
case string:
expr = ConstantOf(v)
case *DocumentRef:
expr = ConstantOf(v)
case Expression:
expr = v
default:
return &baseFunction{baseExpression: &baseExpression{err: fmt.Errorf("firestore: value must be a string, DocumentRef, or Expr, but got %T", exprStringOrDocRef)}}
}
return newBaseFunction("parent", []Expression{expr})
}
// GetField creates an expression that accesses a field/property of a document field using the provided key.
// - exprOrField: The expression representing the document or map.
// - key: The key of the field to access.
func GetField(exprOrField any, key any) Expression {
return newBaseFunction("get_field", []Expression{asFieldExpr(exprOrField), asStringExpr(key)})
}
// Conditional creates an expression that evaluates a condition and returns one of two expressions.
// - condition is the boolean expression to evaluate.
// - thenValOrExpr is the value or expression to return if the condition is true.
// - elseValOrExpr is the value or expression to return if the condition is false.
func Conditional(condition BooleanExpression, thenValOrExpr, elseValOrExpr any) Expression {
return newBaseFunction("conditional", []Expression{condition, toExprOrConstant(thenValOrExpr), toExprOrConstant(elseValOrExpr)})
}
// LogicalMaximum creates an expression that evaluates to the maximum value in a list of expressions.
// - exprOrField can be a field path string, [FieldPath] or an [Expression].
// - others can be a list of constants or [Expression].
func LogicalMaximum(exprOrField any, others ...any) Expression {
return newBaseFunction("maximum", append([]Expression{asFieldExpr(exprOrField)}, toArrayOfExprOrConstant(others)...))
}
// LogicalMinimum creates an expression that evaluates to the minimum value in a list of expressions.
// - exprOrField can be a field path string, [FieldPath] or an [Expression].
// - others can be a list of constants or [Expression].
func LogicalMinimum(exprOrField any, others ...any) Expression {
return newBaseFunction("minimum", append([]Expression{asFieldExpr(exprOrField)}, toArrayOfExprOrConstant(others)...))
}
// IfError creates an expression that evaluates and returns `tryExpr` if it does not produce an error;
// otherwise, it evaluates and returns `catchExprOrValue`. It returns a new [Expression] representing
// the if_error operation.
// - tryExpr is the expression to try.
// - catchExprOrValue is the expression or value to return if `tryExpr` errors.
func IfError(tryExpr Expression, catchExprOrValue any) Expression {
return newBaseFunction("if_error", []Expression{tryExpr, toExprOrConstant(catchExprOrValue)})
}
// IfErrorBoolean creates a boolean expression that evaluates and returns `tryExpr` if it does not produce an error;
// otherwise, it evaluates and returns `catchExpr`. It returns a new [BooleanExpression] representing
// the if_error operation.
// - tryExpr is the boolean expression to try.
// - catchExpr is the boolean expression to return if `tryExpr` errors.
func IfErrorBoolean(tryExpr BooleanExpression, catchExpr BooleanExpression) BooleanExpression {
return &baseBooleanExpression{baseFunction: newBaseFunction("if_error", []Expression{tryExpr, catchExpr})}
}
// IfAbsent creates an expression that returns a default value if an expression evaluates to an absent value.
// - exprOrField is the field or expression to check. It can be a field path string, [FieldPath] or an [Expression].
// - elseValueOrExpr is the value or expression to return if the expression is absent. It can be a constant or an [Expression].
func IfAbsent(exprOrField any, elseValueOrExpr any) Expression {
return newBaseFunction("if_absent", []Expression{asFieldExpr(exprOrField), toExprOrConstant(elseValueOrExpr)})
}
// IfNull creates an expression that returns a default value if an expression evaluates to null.
// Note: This function provides a fallback for both absent and explicit null values. In contrast,
// IfAbsent only triggers for missing fields.
// - exprOrField can be a field path string, [FieldPath] or an [Expression].
// - elseValueOrExpr is the default value or expression to return if the first evaluates to null.
func IfNull(exprOrField any, elseValueOrExpr any) Expression {
return newBaseFunction("if_null", []Expression{asFieldExpr(exprOrField), toExprOrConstant(elseValueOrExpr)})
}
// Coalesce returns the first non-null, non-absent argument, without evaluating the rest of the arguments.
// When all arguments are null or absent, returns the last argument.
// - exprOrField can be a field path string, [FieldPath] or an [Expression].
// - replacement is the fallback expression or value if the first one evaluates to null or is absent.
// - others are optional additional expressions or values to check.
func Coalesce(exprOrField any, replacement any, others ...any) Expression {
exprs := make([]Expression, 0, len(others)+2)
exprs = append(exprs, asFieldExpr(exprOrField), toExprOrConstant(replacement))
for _, v := range others {
exprs = append(exprs, toExprOrConstant(v))
}
return newBaseFunction("coalesce", exprs)
}
// SwitchOn creates an expression that evaluates to the result corresponding to the first true condition.
//
// This function behaves like a `switch` statement. It accepts an alternating sequence of
// conditions and their corresponding results. If an odd number of arguments is provided, the
// final argument serves as a default fallback result. If no default is provided and no condition
// evaluates to true, it throws an error.
//
// - condition: The first condition to check. Must be a [BooleanExpression].
// - result: The result to return if the first condition is true. Can be an [Expression] or a literal value.
// - others: Additional alternating conditions and results, optionally followed by a default fallback value.
//
// Example:
//
// firestore.SwitchOn(
// firestore.FieldOf("score").GreaterThan(90), "A",
// firestore.FieldOf("score").GreaterThan(80), "B",
// "F", // Default result
// )
func SwitchOn(condition BooleanExpression, result any, others ...any) Expression {
exprs := make([]Expression, 0, len(others)+2)
exprs = append(exprs, condition, toExprOrConstant(result))
for _, v := range others {
exprs = append(exprs, toExprOrConstant(v))
}
return newBaseFunction("switch_on", exprs)
}
// Map creates an expression that creates a Firestore map value from an input object.
// - elements: The input map to evaluate in the expression.
func Map(elements map[string]any) Expression {
exprs := make([]Expression, 0, len(elements)*2)
for k, v := range elements {
exprs = append(exprs, ConstantOf(k), toExprOrConstant(v))
}
return newBaseFunction("map", exprs)
}
// MapGet creates an expression that accesses a value from a map (object) field using the provided key.
// - exprOrField: The expression representing the map.
// - strOrExprkey: The key to access in the map.
func MapGet(exprOrField any, strOrExprkey any) Expression {
return newBaseFunction("map_get", []Expression{asFieldExpr(exprOrField), asStringExpr(strOrExprkey)})
}
// MapMerge creates an expression that merges multiple maps into a single map.
// If multiple maps have the same key, the later value is used.
// - exprOrField: First map field path string, [FieldPath] or an [Expression]
// - secondMap: Second map expression that will be merged.
// - otherMaps: Additional maps to merge.
func MapMerge(exprOrField any, secondMap Expression, otherMaps ...Expression) Expression {
return newBaseFunction("map_merge", append([]Expression{asFieldExpr(exprOrField), secondMap}, otherMaps...))
}
// MapRemove creates an expression that removes a key from a map.
// - exprOrField: The expression representing the map.
// - strOrExprkey: The key to remove from the map.
func MapRemove(exprOrField any, strOrExprkey any) Expression {
return newBaseFunction("map_remove", []Expression{asFieldExpr(exprOrField), asStringExpr(strOrExprkey)})
}
// MapSet creates an expression that updates a map with key-value pairs.
// - exprOrField: The expression representing the map.
// - key: The first key to set. It can be a string or an [Expression].
// - value: The first value to set. It can be a literal value or an [Expression].
// - moreKeysAndValues: Optional additional alternating key and value arguments.
func MapSet(exprOrField any, key any, value any, moreKeysAndValues ...any) Expression {
exprs := make([]Expression, 0, len(moreKeysAndValues)+3)
exprs = append(exprs, asFieldExpr(exprOrField), toExprOrConstant(key), toExprOrConstant(value))
for _, v := range moreKeysAndValues {
exprs = append(exprs, toExprOrConstant(v))
}
return newBaseFunction("map_set", exprs)
}
// MapKeys creates an expression that returns the keys of a map as an array.
// - exprOrField: The expression representing the map.
func MapKeys(exprOrField any) Expression {
return newBaseFunction("map_keys", []Expression{asFieldExpr(exprOrField)})
}
// MapValues creates an expression that returns the values of a map as an array.
// - exprOrField: The expression representing the map.
func MapValues(exprOrField any) Expression {
return newBaseFunction("map_values", []Expression{asFieldExpr(exprOrField)})
}
// MapEntries creates an expression that returns the entries of a map as an array of key-value maps.
// - exprOrField: The expression representing the map.
func MapEntries(exprOrField any) Expression {
return newBaseFunction("map_entries", []Expression{asFieldExpr(exprOrField)})
}
// RegexFind creates an expression that returns the first substring that matches the specified regex pattern.
// - exprOrField: The expression representing the string to search.
// - pattern is the regular expression to search for. It can be a string or [Expression] that evaluates to a string.
func RegexFind(exprOrField any, pattern any) Expression {
return newBaseFunction("regex_find", []Expression{asFieldExpr(exprOrField), asStringExpr(pattern)})
}
// RegexFindAll creates an expression that returns all substrings that match the specified regex pattern.
// - exprOrField: The expression representing the string to search.
// - pattern is the regular expression to search for. It can be a string or [Expression] that evaluates to a string.
//
// This expression uses the [RE2](https://github.com/google/re2/wiki/Syntax) regular expression syntax.
func RegexFindAll(exprOrField any, pattern any) Expression {
return newBaseFunction("regex_find_all", []Expression{asFieldExpr(exprOrField), asStringExpr(pattern)})
}
// Rand returns a pseudo-random floating point number, chosen uniformly between 0.0 (inclusive) and 1.0 (exclusive).
func Rand() Expression {
return newBaseFunction("rand", nil)
}
// DocumentMatches creates a boolean expression that performs a full-text search on all indexed search fields in the document.
//
// This Expression can only be used within a Search stage.
//
// Example:
//
// client.Pipeline().Collection("restaurants").
// Search(WithSearchQuery(DocumentMatches("waffles OR pancakes")))
//
// - query: Define the search query using the search domain-specific language (DSL).
//
// Experimental: Update, Delete and Search stages in pipeline queries are in public preview
// and are subject to potential breaking changes in future versions,
// regardless of any other documented package stability guarantees.
func DocumentMatches(query string) BooleanExpression {
return &baseBooleanExpression{baseFunction: newBaseFunction("document_matches", []Expression{ConstantOf(query)})}
}
// GeoDistance creates an expression that evaluates to the distance in meters between the location in the specified field and the query location.
//
// This Expression can only be used within a Search stage.
//
// Example:
//
// client.Pipeline().Collection("restaurants").
// Search(
// WithSearchQuery("waffles"),
// WithSearchSort(Ascending(GeoDistance("location", &latlng.LatLng{Latitude: 37.0, Longitude: -122.0}))),
// )
//
// - field: Specifies the field in the document which contains the GeoPoint for distance computation. It can be a field path string, [FieldPath] or [Expression].
// - location: Compute distance to this GeoPoint.
//
// Experimental: Update, Delete and Search stages in pipeline queries are in public preview
// and are subject to potential breaking changes in future versions,
// regardless of any other documented package stability guarantees.
func GeoDistance(field any, location *latlng.LatLng) Expression {
return newBaseFunction("geo_distance", []Expression{asFieldExpr(field), ConstantOf(location)})
}
// Score creates an expression that evaluates to the search score that reflects the topicality of the document to all of the text
// predicates (for example: DocumentMatches) in the search query.
//
// This Expression can only be used within a Search stage.
//
// Example:
//
// client.Pipeline().Collection("restaurants").
// Search(WithSearchQuery("waffles"), WithSearchSort(Descending(Score())))
//
// Experimental: Update, Delete and Search stages in pipeline queries are in public preview
// and are subject to potential breaking changes in future versions,
// regardless of any other documented package stability guarantees.
func Score() Expression {
return newBaseFunction("score", nil)
}