Skip to content
619 changes: 474 additions & 145 deletions firestore/pipeline.go

Large diffs are not rendered by default.

12 changes: 8 additions & 4 deletions firestore/pipeline_expression.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,12 @@ type Expression interface {
// If the expression resolves to an absent value, it is converted to NULL.
// The order of elements in the output array is not stable and shouldn't be relied upon.
ArrayAggDistinct() AggregateFunction
// TODO: Uncomment this after fixing the proto representation of this function.
// ArrayFilter creates an expression for array_filter(array, param, body).
//
// The parameter 'param' is the name of the parameter to use in the body expression.
// The parameter 'body' is the expression to evaluate for each element of the array.
ArrayFilter(param string, body BooleanExpression) Expression
// ArrayFilter(param string, body BooleanExpression) Expression
// LogicalMaximum returns the maximum value of the expression and the specified values.
LogicalMaximum(others ...any) Expression
// LogicalMinimum returns the minimum value of the expression and the specified values.
Expand Down Expand Up @@ -582,9 +583,12 @@ func (b *baseExpression) First() AggregateFunction { return First(b)
func (b *baseExpression) Last() AggregateFunction { return Last(b) }
func (b *baseExpression) ArrayAgg() AggregateFunction { return ArrayAgg(b) }
func (b *baseExpression) ArrayAggDistinct() AggregateFunction { return ArrayAggDistinct(b) }
func (b *baseExpression) ArrayFilter(param string, body BooleanExpression) Expression {
return ArrayFilter(b, param, body)
}

// TODO: Uncomment this after fixing the proto representation of this function.
//
// func (b *baseExpression) ArrayFilter(param string, body BooleanExpression) Expression {
// return ArrayFilter(b, param, body)
// }
func (b *baseExpression) LogicalMaximum(others ...any) Expression {
return LogicalMaximum(b, others...)
}
Expand Down
7 changes: 4 additions & 3 deletions firestore/pipeline_function.go
Original file line number Diff line number Diff line change
Expand Up @@ -569,9 +569,10 @@ func ArraySliceLength(exprOrFieldPath any, offset any, length any) Expression {
//
// Experimental: Firestore Pipelines is currently in preview and is subject to potential breaking changes in future versions,
// regardless of any other documented package stability guarantees.
func ArrayFilter(array any, param string, body BooleanExpression) Expression {
return newBaseFunction("array_filter", []Expression{asFieldExpr(array), ConstantOf(param), body})
}
// TODO: Uncomment this after fixing the proto representation of this function.
// func ArrayFilter(array any, param string, body BooleanExpression) Expression {
// return newBaseFunction("array_filter", []Expression{asFieldExpr(array), ConstantOf(param), 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.
Expand Down
89 changes: 45 additions & 44 deletions firestore/pipeline_function_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -994,50 +994,51 @@ func TestArrayFunctions(t *testing.T) {
},
}},
},
{
desc: "ArrayFilter",
expr: ArrayFilter("field", "item", FieldOf("item").GreaterThan(5)),
want: &pb.Value{ValueType: &pb.Value_FunctionValue{
FunctionValue: &pb.Function{
Name: "array_filter",
Args: []*pb.Value{
{ValueType: &pb.Value_FieldReferenceValue{FieldReferenceValue: "field"}},
{ValueType: &pb.Value_StringValue{StringValue: "item"}},
{ValueType: &pb.Value_FunctionValue{
FunctionValue: &pb.Function{
Name: "greater_than",
Args: []*pb.Value{
{ValueType: &pb.Value_FieldReferenceValue{FieldReferenceValue: "item"}},
{ValueType: &pb.Value_IntegerValue{IntegerValue: 5}},
},
},
}},
},
},
}},
},
{
desc: "baseExpression ArrayFilter",
expr: FieldOf("field").ArrayFilter("item", FieldOf("item").GreaterThan(5)),
want: &pb.Value{ValueType: &pb.Value_FunctionValue{
FunctionValue: &pb.Function{
Name: "array_filter",
Args: []*pb.Value{
{ValueType: &pb.Value_FieldReferenceValue{FieldReferenceValue: "field"}},
{ValueType: &pb.Value_StringValue{StringValue: "item"}},
{ValueType: &pb.Value_FunctionValue{
FunctionValue: &pb.Function{
Name: "greater_than",
Args: []*pb.Value{
{ValueType: &pb.Value_FieldReferenceValue{FieldReferenceValue: "item"}},
{ValueType: &pb.Value_IntegerValue{IntegerValue: 5}},
},
},
}},
},
},
}},
},
// TODO: Uncomment this after fixing the proto representation of this function.
// {
// desc: "ArrayFilter",
// expr: ArrayFilter("field", "item", FieldOf("item").GreaterThan(5)),
// want: &pb.Value{ValueType: &pb.Value_FunctionValue{
// FunctionValue: &pb.Function{
// Name: "array_filter",
// Args: []*pb.Value{
// {ValueType: &pb.Value_FieldReferenceValue{FieldReferenceValue: "field"}},
// {ValueType: &pb.Value_StringValue{StringValue: "item"}},
// {ValueType: &pb.Value_FunctionValue{
// FunctionValue: &pb.Function{
// Name: "greater_than",
// Args: []*pb.Value{
// {ValueType: &pb.Value_FieldReferenceValue{FieldReferenceValue: "item"}},
// {ValueType: &pb.Value_IntegerValue{IntegerValue: 5}},
// },
// },
// }},
// },
// },
// }},
// },
// {
// desc: "baseExpression ArrayFilter",
// expr: FieldOf("field").ArrayFilter("item", FieldOf("item").GreaterThan(5)),
// want: &pb.Value{ValueType: &pb.Value_FunctionValue{
// FunctionValue: &pb.Function{
// Name: "array_filter",
// Args: []*pb.Value{
// {ValueType: &pb.Value_FieldReferenceValue{FieldReferenceValue: "field"}},
// {ValueType: &pb.Value_StringValue{StringValue: "item"}},
// {ValueType: &pb.Value_FunctionValue{
// FunctionValue: &pb.Function{
// Name: "greater_than",
// Args: []*pb.Value{
// {ValueType: &pb.Value_FieldReferenceValue{FieldReferenceValue: "item"}},
// {ValueType: &pb.Value_IntegerValue{IntegerValue: 5}},
// },
// },
// }},
// },
// },
// }},
// },
{
desc: "ArrayIndexOf",
expr: ArrayIndexOf("field", "search"),
Expand Down
Loading
Loading