Skip to content

Commit 382a5cd

Browse files
committed
add remove fields support
1 parent 17dc248 commit 382a5cd

File tree

4 files changed

+155
-0
lines changed

4 files changed

+155
-0
lines changed

google-cloud-firestore/src/main/java/com/google/cloud/firestore/Pipeline.java

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,14 @@
4141
import com.google.cloud.firestore.pipeline.stages.GenericStage;
4242
import com.google.cloud.firestore.pipeline.stages.Limit;
4343
import com.google.cloud.firestore.pipeline.stages.Offset;
44+
import com.google.cloud.firestore.pipeline.stages.RemoveFields;
4445
import com.google.cloud.firestore.pipeline.stages.Select;
4546
import com.google.cloud.firestore.pipeline.stages.Sort;
4647
import com.google.cloud.firestore.pipeline.stages.Stage;
4748
import com.google.cloud.firestore.pipeline.stages.StageUtils;
4849
import com.google.cloud.firestore.pipeline.stages.Where;
4950
import com.google.common.collect.FluentIterable;
51+
import com.google.common.collect.ImmutableList;
5052
import com.google.common.collect.ImmutableMap;
5153
import com.google.firestore.v1.Document;
5254
import com.google.firestore.v1.ExecutePipelineRequest;
@@ -56,6 +58,7 @@
5658
import io.opencensus.trace.AttributeValue;
5759
import io.opencensus.trace.Tracing;
5860
import java.util.ArrayList;
61+
import java.util.Arrays;
5962
import java.util.List;
6063
import java.util.logging.Level;
6164
import java.util.logging.Logger;
@@ -165,6 +168,52 @@ public Pipeline addFields(Selectable... fields) {
165168
return append(new AddFields(PipelineUtils.selectablesToMap(fields)));
166169
}
167170

171+
/**
172+
* Remove fields from outputs of previous stages.
173+
*
174+
* <p>Example:
175+
*
176+
* <pre>{@code
177+
* firestore.pipeline().collection("books")
178+
* .removeFields(
179+
* "rating", "cost"
180+
* );
181+
* }</pre>
182+
*
183+
* @param fields The fields to remove.
184+
* @return A new Pipeline object with this stage appended to the stage list.
185+
*/
186+
@BetaApi
187+
public Pipeline removeFields(String... fields) {
188+
return append(
189+
new RemoveFields(
190+
ImmutableList.<Field>builder()
191+
.addAll(Arrays.stream(fields).map(f -> Field.of(f)).iterator())
192+
.build()));
193+
}
194+
195+
/**
196+
* Remove fields from outputs of previous stages.
197+
*
198+
* <p>Example:
199+
*
200+
* <pre>{@code
201+
* firestore.pipeline().collection("books")
202+
* .removeFields(
203+
* Field.of("rating"), Field.of("cost")
204+
* );
205+
* }</pre>
206+
*
207+
* @param fields The fields to remove.
208+
* @return A new Pipeline object with this stage appended to the stage list.
209+
*/
210+
@BetaApi
211+
public Pipeline removeFields(Field... fields) {
212+
return append(
213+
new RemoveFields(
214+
ImmutableList.<Field>builder().addAll(Arrays.stream(fields).iterator()).build()));
215+
}
216+
168217
/**
169218
* Selects or creates a set of fields from the outputs of previous stages.
170219
*
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Copyright 2024 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.firestore.pipeline.stages;
18+
19+
import com.google.api.core.InternalApi;
20+
import com.google.cloud.firestore.pipeline.expressions.Field;
21+
import com.google.common.collect.ImmutableList;
22+
23+
@InternalApi
24+
public final class RemoveFields implements Stage {
25+
26+
private static final String name = "remove_fields";
27+
private final ImmutableList<Field> fields;
28+
29+
@InternalApi
30+
public RemoveFields(ImmutableList<Field> fields) {
31+
this.fields = fields;
32+
}
33+
34+
@InternalApi
35+
public ImmutableList<Field> getFields() {
36+
return fields;
37+
}
38+
39+
@Override
40+
public String getName() {
41+
return name;
42+
}
43+
}

google-cloud-firestore/src/main/java/com/google/cloud/firestore/pipeline/stages/StageUtils.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ public static com.google.firestore.v1.Pipeline.Stage toStageProto(Stage stage) {
6868
.setName(addFieldsStage.getName())
6969
.addArgs(encodeValue(addFieldsStage.getFields()))
7070
.build();
71+
} else if (stage instanceof RemoveFields) {
72+
RemoveFields removeFieldsStage = (RemoveFields) stage;
73+
return com.google.firestore.v1.Pipeline.Stage.newBuilder()
74+
.setName(removeFieldsStage.getName())
75+
.addAllArgs(
76+
removeFieldsStage.getFields().stream()
77+
.map(f -> encodeValue(f))
78+
.collect(Collectors.toList()))
79+
.build();
7180
} else if (stage instanceof Where) {
7281
Where whereStage = (Where) stage; // Use wildcard for generic type
7382
return com.google.firestore.v1.Pipeline.Stage.newBuilder()

google-cloud-firestore/src/test/java/com/google/cloud/firestore/it/ITPipelineTest.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,60 @@ public void selectSpecificFields() throws Exception {
364364
map("title", "The Handmaid's Tale", "author", "Margaret Atwood")));
365365
}
366366

367+
@Test
368+
public void addAndRemoveFields() throws Exception {
369+
List<PipelineResult> results =
370+
firestore
371+
.pipeline()
372+
.collection(collection.getPath())
373+
.addFields(
374+
strConcat(Field.of("author"), "_", Field.of("title")).as("author_title"),
375+
strConcat(Field.of("title"), "_", Field.of("author")).as("title_author"))
376+
.removeFields("title_author", "tags", "awards", "rating", "title")
377+
.removeFields(Field.of("published"), Field.of("genre"), Field.of("nestedField"))
378+
.sort(Field.of("author_title").ascending())
379+
.execute()
380+
.get();
381+
382+
assertThat(data(results))
383+
.isEqualTo(
384+
Lists.newArrayList(
385+
map(
386+
"author_title",
387+
"Douglas Adams_The Hitchhiker's Guide to the Galaxy",
388+
"author",
389+
"Douglas Adams"),
390+
map(
391+
"author_title",
392+
"F. Scott Fitzgerald_The Great Gatsby",
393+
"author",
394+
"F. Scott Fitzgerald"),
395+
map("author_title", "Frank Herbert_Dune", "author", "Frank Herbert"),
396+
map(
397+
"author_title",
398+
"Fyodor Dostoevsky_Crime and Punishment",
399+
"author",
400+
"Fyodor Dostoevsky"),
401+
map(
402+
"author_title",
403+
"Gabriel García Márquez_One Hundred Years of Solitude",
404+
"author",
405+
"Gabriel García Márquez"),
406+
map("author_title", "George Orwell_1984", "author", "George Orwell"),
407+
map("author_title", "Harper Lee_To Kill a Mockingbird", "author", "Harper Lee"),
408+
map(
409+
"author_title",
410+
"J.R.R. Tolkien_The Lord of the Rings",
411+
"author",
412+
"J.R.R. Tolkien"),
413+
map("author_title", "Jane Austen_Pride and Prejudice", "author", "Jane Austen"),
414+
map(
415+
"author_title",
416+
"Margaret Atwood_The Handmaid's Tale",
417+
"author",
418+
"Margaret Atwood")));
419+
}
420+
367421
@Test
368422
public void whereByMultipleConditions() throws Exception {
369423
List<PipelineResult> results =

0 commit comments

Comments
 (0)