Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add datastore aggregation query APIs #1008

Merged
merged 2 commits into from
Oct 18, 2022
Merged
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
61 changes: 61 additions & 0 deletions protos/google/datastore/v1/aggregation_result.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright 2022 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.

syntax = "proto3";

package google.datastore.v1;

import "google/datastore/v1/entity.proto";
import "google/datastore/v1/query.proto";
import "google/protobuf/timestamp.proto";

option csharp_namespace = "Google.Cloud.Datastore.V1";
option go_package = "google.golang.org/genproto/googleapis/datastore/v1;datastore";
option java_multiple_files = true;
option java_outer_classname = "AggregationResultProto";
option java_package = "com.google.datastore.v1";
option php_namespace = "Google\\Cloud\\Datastore\\V1";
option ruby_package = "Google::Cloud::Datastore::V1";

// The result of a single bucket from a Datastore aggregation query.
//
// The keys of `aggregate_properties` are the same for all results in an
// aggregation query, unlike entity queries which can have different fields
// present for each result.
message AggregationResult {
// The result of the aggregation functions, ex: `COUNT(*) AS total_entities`.
//
// The key is the [alias][google.datastore.v1.AggregationQuery.Aggregation.alias]
// assigned to the aggregation function on input and the size of this map
// equals the number of aggregation functions in the query.
map<string, Value> aggregate_properties = 2;
}

// A batch of aggregation results produced by an aggregation query.
message AggregationResultBatch {
// The aggregation results for this batch.
repeated AggregationResult aggregation_results = 1;

// The state of the query after the current batch.
// Only COUNT(*) aggregations are supported in the initial launch. Therefore,
// expected result type is limited to `NO_MORE_RESULTS`.
QueryResultBatch.MoreResultsType more_results = 2;

// Read timestamp this batch was returned from.
//
// In a single transaction, subsequent query result batches for the same query
// can have a greater timestamp. Each batch's read timestamp
// is valid for all preceding batches.
google.protobuf.Timestamp read_time = 3;
}
48 changes: 48 additions & 0 deletions protos/google/datastore/v1/datastore.proto
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package google.datastore.v1;
import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/datastore/v1/aggregation_result.proto";
import "google/datastore/v1/entity.proto";
import "google/datastore/v1/query.proto";
import "google/protobuf/timestamp.proto";
Expand Down Expand Up @@ -61,6 +62,14 @@ service Datastore {
};
}

// Runs an aggregation query.
rpc RunAggregationQuery(RunAggregationQueryRequest) returns (RunAggregationQueryResponse) {
option (google.api.http) = {
post: "/v1/projects/{project_id}:runAggregationQuery"
body: "*"
};
}

// Begins a new transaction.
rpc BeginTransaction(BeginTransactionRequest) returns (BeginTransactionResponse) {
option (google.api.http) = {
Expand Down Expand Up @@ -189,6 +198,45 @@ message RunQueryResponse {
Query query = 2;
}

// The request for [Datastore.RunAggregationQuery][google.datastore.v1.Datastore.RunAggregationQuery].
message RunAggregationQueryRequest {
// Required. The ID of the project against which to make the request.
string project_id = 8 [(google.api.field_behavior) = REQUIRED];

// The ID of the database against which to make the request.
//
// '(default)' is not allowed; please use empty string '' to refer the default
// database.
string database_id = 9;

// Entities are partitioned into subsets, identified by a partition ID.
// Queries are scoped to a single partition.
// This partition ID is normalized with the standard default context
// partition ID.
PartitionId partition_id = 2;

// The options for this query.
ReadOptions read_options = 1;

// The type of query.
oneof query_type {
// The query to run.
AggregationQuery aggregation_query = 3;

// The GQL query to run. This query must be an aggregation query.
GqlQuery gql_query = 7;
}
}

// The response for [Datastore.RunAggregationQuery][google.datastore.v1.Datastore.RunAggregationQuery].
message RunAggregationQueryResponse {
// A batch of aggregation results. Always present.
AggregationResultBatch batch = 1;

// The parsed form of the `GqlQuery` from the request, if it was set.
AggregationQuery query = 2;
}

// The request for [Datastore.BeginTransaction][google.datastore.v1.Datastore.BeginTransaction].
message BeginTransactionRequest {
// Required. The ID of the project against which to make the request.
Expand Down
87 changes: 87 additions & 0 deletions protos/google/datastore/v1/query.proto
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,93 @@ message Query {
google.protobuf.Int32Value limit = 12;
}

// Datastore query for running an aggregation over a [Query][google.datastore.v1.Query].
message AggregationQuery {
// Defines a aggregation that produces a single result.
message Aggregation {
// Count of entities that match the query.
//
// The `COUNT(*)` aggregation function operates on the entire entity
// so it does not require a field reference.
message Count {
// Optional. Optional constraint on the maximum number of entities to count.
//
// This provides a way to set an upper bound on the number of entities
// to scan, limiting latency and cost.
//
// Unspecified is interpreted as no bound.
//
// If a zero value is provided, a count result of zero should always be
// expected.
//
// High-Level Example:
//
// ```
// AGGREGATE COUNT_UP_TO(1000) OVER ( SELECT * FROM k );
// ```
//
// Requires:
//
// * Must be non-negative when present.
google.protobuf.Int64Value up_to = 1 [(google.api.field_behavior) = OPTIONAL];
}

// The type of aggregation to perform, required.
oneof operator {
// Count aggregator.
Count count = 1;
}

// Optional. Optional name of the property to store the result of the aggregation.
//
// If not provided, Datastore will pick a default name following the format
// `property_<incremental_id++>`. For example:
//
// ```
// AGGREGATE
// COUNT_UP_TO(1) AS count_up_to_1,
// COUNT_UP_TO(2),
// COUNT_UP_TO(3) AS count_up_to_3,
// COUNT_UP_TO(4)
// OVER (
// ...
// );
// ```
//
// becomes:
//
// ```
// AGGREGATE
// COUNT_UP_TO(1) AS count_up_to_1,
// COUNT_UP_TO(2) AS property_1,
// COUNT_UP_TO(3) AS count_up_to_3,
// COUNT_UP_TO(4) AS property_2
// OVER (
// ...
// );
// ```
//
// Requires:
//
// * Must be unique across all aggregation aliases.
// * Conform to [entity property name][google.datastore.v1.Entity.properties] limitations.
string alias = 7 [(google.api.field_behavior) = OPTIONAL];
}

// The base query to aggregate over.
oneof query_type {
// Nested query for aggregation
Query nested_query = 1;
}

// Optional. Series of aggregations to apply over the results of the `nested_query`.
//
// Requires:
//
// * A minimum of one and maximum of five aggregations per query.
repeated Aggregation aggregations = 3 [(google.api.field_behavior) = OPTIONAL];
}

// A representation of a kind.
message KindExpression {
// The name of the kind.
Expand Down
Loading