Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,13 @@
import com.google.cloud.firestore.pipeline.stages.AddFields;
import com.google.cloud.firestore.pipeline.stages.Aggregate;
import com.google.cloud.firestore.pipeline.stages.AggregateOptions;
import com.google.cloud.firestore.pipeline.stages.Delete;
import com.google.cloud.firestore.pipeline.stages.DeleteOptions;
import com.google.cloud.firestore.pipeline.stages.Distinct;
import com.google.cloud.firestore.pipeline.stages.FindNearest;
import com.google.cloud.firestore.pipeline.stages.FindNearestOptions;
import com.google.cloud.firestore.pipeline.stages.Insert;
import com.google.cloud.firestore.pipeline.stages.InsertOptions;
import com.google.cloud.firestore.pipeline.stages.Limit;
import com.google.cloud.firestore.pipeline.stages.Offset;
import com.google.cloud.firestore.pipeline.stages.PipelineExecuteOptions;
Expand All @@ -58,6 +62,8 @@
import com.google.cloud.firestore.pipeline.stages.Union;
import com.google.cloud.firestore.pipeline.stages.Unnest;
import com.google.cloud.firestore.pipeline.stages.UnnestOptions;
import com.google.cloud.firestore.pipeline.stages.Upsert;
import com.google.cloud.firestore.pipeline.stages.UpsertOptions;
import com.google.cloud.firestore.pipeline.stages.Where;
import com.google.cloud.firestore.telemetry.MetricsUtil.MetricsContext;
import com.google.cloud.firestore.telemetry.TelemetryConstants;
Expand Down Expand Up @@ -995,6 +1001,105 @@ public Pipeline unnest(Selectable field, UnnestOptions options) {
return append(new Unnest(field, options));
}

/**
* Performs a delete operation on documents from previous stages.
*
* @return A new {@code Pipeline} object with this stage appended to the stage list.
*/
@BetaApi
public Pipeline delete() {
return append(new Delete());
}

/**
* Performs a delete operation on documents from previous stages.
*
* @param target The collection to delete from.
* @return A new {@code Pipeline} object with this stage appended to the stage list.
*/
@BetaApi
public Pipeline delete(CollectionReference target) {
return append(Delete.withCollection(target));
}

/**
* Performs a delete operation on documents from previous stages.
*
* @param deleteStage The {@code Delete} stage to append.
* @param options The {@code DeleteOptions} to apply to the stage.
* @return A new {@code Pipeline} object with this stage appended to the stage list.
*/
@BetaApi
public Pipeline delete(Delete deleteStage, DeleteOptions options) {
return append(deleteStage.withOptions(options));
}

/**
* Performs an upsert operation using documents from previous stages.
*
* @return A new {@code Pipeline} object with this stage appended to the stage list.
*/
@BetaApi
public Pipeline upsert() {
return append(new Upsert());
}

/**
* Performs an upsert operation using documents from previous stages.
*
* @param target The collection to upsert to.
* @return A new {@code Pipeline} object with this stage appended to the stage list.
*/
@BetaApi
public Pipeline upsert(CollectionReference target) {
return append(Upsert.withCollection(target));
}

/**
* Performs an upsert operation using documents from previous stages.
*
* @param upsertStage The {@code Upsert} stage to append.
* @param options The {@code UpsertOptions} to apply to the stage.
* @return A new {@code Pipeline} object with this stage appended to the stage list.
*/
@BetaApi
public Pipeline upsert(Upsert upsertStage, UpsertOptions options) {
return append(upsertStage.withOptions(options));
}

/**
* Performs an insert operation using documents from previous stages.
*
* @return A new {@code Pipeline} object with this stage appended to the stage list.
*/
@BetaApi
public Pipeline insert() {
return append(new Insert());
}

/**
* Performs an insert operation using documents from previous stages.
*
* @param target The collection to insert to.
* @return A new {@code Pipeline} object with this stage appended to the stage list.
*/
@BetaApi
public Pipeline insert(CollectionReference target) {
return append(Insert.withCollection(target));
}

/**
* Performs an insert operation using documents from previous stages.
*
* @param insertStage The {@code Insert} stage to append.
* @param options The {@code InsertOptions} to apply to the stage.
* @return A new {@code Pipeline} object with this stage appended to the stage list.
*/
@BetaApi
public Pipeline insert(Insert insertStage, InsertOptions options) {
return append(insertStage.withOptions(options));
}

/**
* Adds a generic stage to the pipeline.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* 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 com.google.cloud.firestore.pipeline.stages;

/** Defines the conflict resolution options for an Upsert pipeline stage. */
public enum ConflictResolution {
OVERWRITE("OVERWRITE"),
MERGE("MERGE"),
FAIL("FAIL"),
KEEP("KEEP");

private final String value;

ConflictResolution(String value) {
this.value = value;
}

public String getValue() {
return value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright 2024 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 com.google.cloud.firestore.pipeline.stages;

import com.google.api.core.BetaApi;
import com.google.api.core.InternalApi;
import com.google.cloud.firestore.CollectionReference;
import com.google.cloud.firestore.PipelineUtils;
import com.google.firestore.v1.Value;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;

@InternalApi
public final class Delete extends Stage {

@Nullable private final String path;

private Delete(@Nullable String path, InternalOptions options) {
super("delete", options);
this.path = path;
}

@BetaApi
public Delete() {
this(null, InternalOptions.EMPTY);
}

@BetaApi
public static Delete withCollection(CollectionReference target) {
String path = target.getPath();
return new Delete(path.startsWith("/") ? path : "/" + path, InternalOptions.EMPTY);
}

@BetaApi
public Delete withOptions(DeleteOptions options) {
return new Delete(path, this.options.adding(options));
}

@BetaApi
public Delete withReturns(DeleteReturn returns) {
return new Delete(
path, this.options.with("returns", PipelineUtils.encodeValue(returns.getValue())));
}

@Override
Iterable<Value> toStageArgs() {
List<Value> args = new ArrayList<>();
if (path != null) {
args.add(Value.newBuilder().setReferenceValue(path).build());
}
return args;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2024 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 com.google.cloud.firestore.pipeline.stages;

import com.google.api.core.BetaApi;

/** Options for a Delete pipeline stage. */
@BetaApi
public class DeleteOptions extends WriteOptions<DeleteOptions> {

/** Creates a new, empty `DeleteOptions` object. */
public DeleteOptions() {
super(InternalOptions.EMPTY);
}

DeleteOptions(InternalOptions options) {
super(options);
}

@Override
DeleteOptions self(InternalOptions options) {
return new DeleteOptions(options);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* 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 com.google.cloud.firestore.pipeline.stages;

/** Defines the return value options for a Delete pipeline stage. */
public enum DeleteReturn {
EMPTY("EMPTY"),
DOCUMENT_ID("DOCUMENT_ID");

private final String value;

DeleteReturn(String value) {
this.value = value;
}

public String getValue() {
return value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2024 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 com.google.cloud.firestore.pipeline.stages;

import com.google.api.core.BetaApi;
import com.google.api.core.InternalApi;
import com.google.cloud.firestore.CollectionReference;
import com.google.cloud.firestore.PipelineUtils;
import com.google.cloud.firestore.pipeline.expressions.Selectable;
import com.google.firestore.v1.Value;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Nullable;

@InternalApi
public final class Insert extends Stage {

@Nullable private final String path;

private Insert(@Nullable String path, InternalOptions options) {
super("insert", options);
this.path = path;
}

@BetaApi
public Insert() {
this(null, InternalOptions.EMPTY);
}

@BetaApi
public static Insert withCollection(CollectionReference target) {
String path = target.getPath();
return new Insert(path.startsWith("/") ? path : "/" + path, InternalOptions.EMPTY);
}

@BetaApi
public Insert withOptions(InsertOptions options) {
return new Insert(path, this.options.adding(options));
}

@BetaApi
public Insert withReturns(InsertReturn returns) {
return new Insert(
path, this.options.with("returns", PipelineUtils.encodeValue(returns.getValue())));
}

@BetaApi
public Insert withTransformations(Selectable... transformations) {
return new Insert(
path,
this.options.with(
"transformations",
PipelineUtils.encodeValue(PipelineUtils.selectablesToMap(transformations))));
}

@Override
Iterable<Value> toStageArgs() {
List<Value> args = new ArrayList<>();
if (path != null) {
args.add(Value.newBuilder().setReferenceValue(path).build());
}
return args;
}
}
Loading
Loading