Skip to content

Commit 582c403

Browse files
committed
COUNT API added
1 parent f73d432 commit 582c403

File tree

6 files changed

+323
-0
lines changed

6 files changed

+323
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.firestore;
16+
17+
/**
18+
* The mode in which to execute an aggregate query.
19+
*
20+
* <p>The choice of mode has a dramatic impact on the cost, computation, and latency of aggregate
21+
* queries. It also has impacts on the <em>correctness</em> of aggregations in the presence of local
22+
* writes that have not yet been sync'd with the server.
23+
*/
24+
public enum AggregateExecutionMode {
25+
26+
/**
27+
* Run the full query and perform the aggregations locally.
28+
*
29+
* <p>The advantage of this mode is that the aggregate results are always correct and consistent
30+
* with any other query results, even in the presence of local writes that have not yet been
31+
* sync'd to the server and even when offline.
32+
*
33+
* <p>The drawback of this mode is that query execution is quite costly, as it simply executes the
34+
* underlying query and performs the aggregations locally. This involves downloading all documents
35+
* that match the underlying query, and therefore is slow and incurs billed document reads just as
36+
* if the underlying query were executed directly.
37+
*/
38+
LOCAL,
39+
40+
/**
41+
* Run the query on the server and perform the aggregations on the server.
42+
*
43+
* <p>The advantage of this mode is that it is fast and incurs an order of magnitude fewer billed
44+
* document reads. It is fast because only the <em>aggregate results</em> are downloaded from the
45+
* server and not the documents' full contents.
46+
*
47+
* <p>The drawback of this mode is that the aggregate results can be temporarily inaccurate when
48+
* the client is offline and/or there are local writes that have no yet been sync'd to the server.
49+
* For example, counts could be off by 1 for each mutated document and mutated documents could be
50+
* members of the wrong group.
51+
*/
52+
REMOTE,
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.firestore;
16+
17+
import androidx.annotation.NonNull;
18+
import androidx.annotation.Nullable;
19+
import java.util.Objects;
20+
21+
public abstract class AggregateField {
22+
23+
private AggregateField() {}
24+
25+
@NonNull
26+
public static CountAggregateField count() {
27+
return new CountAggregateField();
28+
}
29+
30+
@Override
31+
public abstract boolean equals(Object obj);
32+
33+
@Override
34+
public abstract int hashCode();
35+
36+
@Override
37+
public abstract String toString();
38+
39+
public static final class CountAggregateField extends AggregateField {
40+
41+
@Nullable private Integer upTo;
42+
43+
CountAggregateField() {}
44+
45+
CountAggregateField(@Nullable Integer upTo) {
46+
this.upTo = upTo;
47+
}
48+
49+
public CountAggregateField upTo(int upTo) {
50+
if (upTo < 0) {
51+
throw new IllegalArgumentException("upTo==" + upTo);
52+
}
53+
return new CountAggregateField(upTo);
54+
}
55+
56+
@Override
57+
public boolean equals(Object obj) {
58+
if (obj == null || obj.getClass() != this.getClass()) {
59+
return false;
60+
}
61+
CountAggregateField other = (CountAggregateField) obj;
62+
return Objects.equals(upTo, other.upTo);
63+
}
64+
65+
@Override
66+
public int hashCode() {
67+
return Objects.hash("COUNT", upTo);
68+
}
69+
70+
@Override
71+
public String toString() {
72+
if (upTo == null) {
73+
return "COUNT";
74+
} else {
75+
return "COUNT(upTo=" + upTo + ")";
76+
}
77+
}
78+
}
79+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.firestore;
16+
17+
import android.app.Activity;
18+
import androidx.annotation.NonNull;
19+
import com.google.android.gms.tasks.Task;
20+
import java.util.concurrent.Executor;
21+
22+
public class AggregateQuery {
23+
24+
AggregateQuery() {}
25+
26+
@NonNull
27+
public Query getQuery() {
28+
throw new RuntimeException("not implemented");
29+
}
30+
31+
@NonNull
32+
public Task<AggregateQuerySnapshot> get() {
33+
throw new RuntimeException("not implemented");
34+
}
35+
36+
@NonNull
37+
public Task<AggregateQuerySnapshot> get(@NonNull Source source) {
38+
throw new RuntimeException("not implemented");
39+
}
40+
41+
@NonNull
42+
public ListenerRegistration addSnapshotListener(
43+
@NonNull EventListener<AggregateQuerySnapshot> listener) {
44+
throw new RuntimeException("not implemented");
45+
}
46+
47+
@NonNull
48+
public ListenerRegistration addSnapshotListener(
49+
@NonNull Executor executor, @NonNull EventListener<AggregateQuerySnapshot> listener) {
50+
throw new RuntimeException("not implemented");
51+
}
52+
53+
@NonNull
54+
public ListenerRegistration addSnapshotListener(
55+
@NonNull Activity activity, @NonNull EventListener<AggregateQuerySnapshot> listener) {
56+
throw new RuntimeException("not implemented");
57+
}
58+
59+
@NonNull
60+
public ListenerRegistration addSnapshotListener(
61+
@NonNull MetadataChanges metadataChanges,
62+
@NonNull EventListener<AggregateQuerySnapshot> listener) {
63+
throw new RuntimeException("not implemented");
64+
}
65+
66+
@NonNull
67+
public ListenerRegistration addSnapshotListener(
68+
@NonNull Executor executor,
69+
@NonNull MetadataChanges metadataChanges,
70+
@NonNull EventListener<AggregateQuerySnapshot> listener) {
71+
throw new RuntimeException("not implemented");
72+
}
73+
74+
@NonNull
75+
public ListenerRegistration addSnapshotListener(
76+
@NonNull Activity activity,
77+
@NonNull MetadataChanges metadataChanges,
78+
@NonNull EventListener<AggregateQuerySnapshot> listener) {
79+
throw new RuntimeException("not implemented");
80+
}
81+
82+
@Override
83+
public int hashCode() {
84+
throw new RuntimeException("not implemented");
85+
}
86+
87+
@Override
88+
public boolean equals(Object obj) {
89+
throw new RuntimeException("not implemented");
90+
}
91+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.firestore;
16+
17+
import androidx.annotation.NonNull;
18+
import javax.annotation.Nonnull;
19+
20+
public class AggregateQuerySnapshot extends AggregateSnapshot {
21+
22+
AggregateQuerySnapshot() {}
23+
24+
@Nonnull
25+
public AggregateQuery getQuery() {
26+
throw new RuntimeException("not implemented");
27+
}
28+
29+
@NonNull
30+
public SnapshotMetadata getMetadata() {
31+
throw new RuntimeException("not implemented");
32+
}
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2022 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package com.google.firebase.firestore;
16+
17+
import androidx.annotation.Nullable;
18+
import javax.annotation.Nonnull;
19+
20+
public class AggregateSnapshot {
21+
22+
AggregateSnapshot() {}
23+
24+
@Nullable
25+
public Long get(@Nonnull AggregateField.CountAggregateField field) {
26+
throw new RuntimeException("not implemented");
27+
}
28+
29+
@Override
30+
public boolean equals(@Nullable Object obj) {
31+
throw new RuntimeException("not implemented");
32+
}
33+
34+
@Override
35+
public int hashCode() {
36+
throw new RuntimeException("not implemented");
37+
}
38+
39+
@Override
40+
public String toString() {
41+
throw new RuntimeException("not implemented");
42+
}
43+
}

firebase-firestore/src/main/java/com/google/firebase/firestore/Query.java

+24
Original file line numberDiff line numberDiff line change
@@ -1223,6 +1223,30 @@ private void validateHasExplicitOrderByForLimitToLast() {
12231223
}
12241224
}
12251225

1226+
@NonNull
1227+
public AggregateQuery aggregate(@NonNull AggregateField field) {
1228+
throw new RuntimeException("not implemented");
1229+
}
1230+
1231+
@NonNull
1232+
public AggregateQuery aggregate(
1233+
@NonNull AggregateExecutionMode mode, @NonNull AggregateField field) {
1234+
throw new RuntimeException("not implemented");
1235+
}
1236+
1237+
// A convenience method for just getting the count of a query.
1238+
// This method also helps with visibility of the "count" feature, since "aggregate" is
1239+
// less obvious what you can do with it.
1240+
@NonNull
1241+
public AggregateQuery count() {
1242+
return aggregate(AggregateField.count());
1243+
}
1244+
1245+
@NonNull
1246+
public AggregateQuery count(@NonNull AggregateExecutionMode mode) {
1247+
return aggregate(mode, AggregateField.count());
1248+
}
1249+
12261250
@Override
12271251
public boolean equals(Object o) {
12281252
if (this == o) {

0 commit comments

Comments
 (0)