Class: Google::Cloud::Datastore::Dataset

Inherits:
Object
  • Object
show all
Defined in:
lib/google/cloud/datastore/dataset.rb,
lib/google/cloud/datastore/dataset/query_results.rb,
lib/google/cloud/datastore/dataset/lookup_results.rb,
lib/google/cloud/datastore/dataset/aggregate_query_results.rb

Overview

Dataset

Dataset is the data saved in a project's Datastore. Dataset is analogous to a database in relational database world.

Dataset is the main object for interacting with Google Datastore. Entity objects are created, read, updated, and deleted by Dataset.

See Google::Cloud#datastore

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query("Task").
  where("done", "=", false)

tasks = datastore.run query

Direct Known Subclasses

Transaction

Defined Under Namespace

Classes: AggregateQueryResults, LookupResults, QueryResults

Instance Method Summary collapse

Instance Method Details

#allocate_ids(incomplete_key, count = 1) ⇒ Array<Google::Cloud::Datastore::Key>

Generate IDs for a Key before creating an entity.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task_key = datastore.key "Task"
task_keys = datastore.allocate_ids task_key, 5

Parameters:

  • incomplete_key (Key)

    A Key without id or name set.

  • count (String) (defaults to: 1)

    The number of new key IDs to create.

Returns:



123
124
125
126
127
128
129
130
131
132
# File 'lib/google/cloud/datastore/dataset.rb', line 123

def allocate_ids incomplete_key, count = 1
  if incomplete_key.complete?
    raise Datastore::KeyError, "An incomplete key must be provided."
  end

  ensure_service!
  incomplete_keys = Array.new(count) { incomplete_key.to_grpc }
  allocate_res = service.allocate_ids(*incomplete_keys)
  allocate_res.keys.map { |key| Key.from_grpc key }
end

#commit {|commit| ... } ⇒ Array<Google::Cloud::Datastore::Entity>

Make multiple changes in a single commit.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

datastore.commit do |c|
  c.save task3, task4
  c.delete task1, task2
end

Yields:

  • (commit)

    a block for making changes

Yield Parameters:

  • commit (Commit)

    The object that changes are made on

Returns:



309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
# File 'lib/google/cloud/datastore/dataset.rb', line 309

def commit
  return unless block_given?
  c = Commit.new
  yield c

  ensure_service!
  commit_res = service.commit c.mutations
  entities = c.entities
  returned_keys = commit_res.mutation_results.map(&:key)
  returned_keys.each_with_index do |key, index|
    next if entities[index].nil?
    entities[index].key = Key.from_grpc key unless key.nil?
  end
  entities.each { |e| e.key.freeze unless e.persisted? }
  entities
end

#database_idString

The Datastore database connected to.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new(
  project_id: "my-todo-project",
  credentials: "/path/to/keyfile.json",
  database_id: "my-database"
)

datastore.database_id #=> "my-database"

Returns:

  • (String)

    ID of the database



103
104
105
# File 'lib/google/cloud/datastore/dataset.rb', line 103

def database_id
  service.database
end

#delete(*entities_or_keys) ⇒ Boolean

Remove entities from the Datastore.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

datastore.delete task1, task2

Parameters:

  • entities_or_keys (Entity, Key)

    One or more Entity or Key objects to remove.

Returns:

  • (Boolean)

    Returns true if successful



285
286
287
288
# File 'lib/google/cloud/datastore/dataset.rb', line 285

def delete *entities_or_keys
  commit { |c| c.delete(*entities_or_keys) }
  true
end

#entity(*key_or_path, project: nil, namespace: nil) {|entity| ... } ⇒ Google::Cloud::Datastore::Entity

Create a new empty Entity instance. This is a convenience method to make the creation of Entity objects easier.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task = datastore.entity

The previous example is equivalent to:

require "google/cloud/datastore"

task = Google::Cloud::Datastore::Entity.new

The key can also be passed in as an object:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task_key = datastore.key "Task", "sampleTask"
task = datastore.entity task_key

Or the key values can be passed in as parameters:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task = datastore.entity "Task", "sampleTask"

The previous example is equivalent to:

require "google/cloud/datastore"

task_key = Google::Cloud::Datastore::Key.new "Task", "sampleTask"
task = Google::Cloud::Datastore::Entity.new
task.key = task_key

The newly created entity can also be configured using block:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task = datastore.entity "Task", "sampleTask" do |t|
  t["type"] = "Personal"
  t["done"] = false
  t["priority"] = 4
  t["description"] = "Learn Cloud Datastore"
end

The previous example is equivalent to:

require "google/cloud/datastore"

task_key = Google::Cloud::Datastore::Key.new "Task", "sampleTask"
task = Google::Cloud::Datastore::Entity.new
task.key = task_key
task["type"] = "Personal"
task["done"] = false
task["priority"] = 4
task["description"] = "Learn Cloud Datastore"

Parameters:

  • key_or_path (Key, Array<Array(String,(String|Integer|nil))>)

    An optional list of pairs for the key's path. Each pair may include the key's kind (String) and an id (Integer) or name (String). This is optional.

  • project (String) (defaults to: nil)

    The project of the Key. This is optional.

  • namespace (String) (defaults to: nil)

    namespace kind of the Key. This is optional.

Yields:

  • (entity)

    a block yielding a new entity

Yield Parameters:

  • entity (Entity)

    the newly created entity object

Returns:



1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
# File 'lib/google/cloud/datastore/dataset.rb', line 1044

def entity *key_or_path, project: nil, namespace: nil
  entity = Entity.new

  # Set the key
  entity.key = if key_or_path.flatten.first.is_a? Datastore::Key
                 key_or_path.flatten.first
               else
                 key key_or_path, project: project, namespace: namespace
               end

  yield entity if block_given?

  entity
end

#filter(name, operator, value) ⇒ Google::Cloud::Datastore::Filter

Create a new Filter instance. This is a convenience method to make the creation of Filter objects easier.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

filter = datastore.filter("done", "=", false)

Parameters:

  • name (String)

    The property to filter by.

  • operator (String)

    The operator to filter by. Defaults to nil.

  • value (Object)

    The value to compare the property to. Defaults to nil. Possible values are:

    • Integer
    • Float/BigDecimal
    • String
    • Boolean
    • Array
    • Date/Time
    • StringIO
    • Google::Cloud::Datastore::Key
    • Google::Cloud::Datastore::Entity
    • nil

Returns:



1087
1088
1089
# File 'lib/google/cloud/datastore/dataset.rb', line 1087

def filter name, operator, value
  Filter.new name, operator, value
end

#find(key_or_kind, id_or_name = nil, consistency: nil, read_time: nil) ⇒ Google::Cloud::Datastore::Entity? Also known as: get

Retrieve an entity by key.

Examples:

Finding an entity with a key:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task_key = datastore.key "Task", "sampleTask"
task = datastore.find task_key

Finding an entity with a kind and id/name:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task = datastore.find "Task", "sampleTask"

Parameters:

  • key_or_kind (Key, String)

    A Key object or kind string value.

  • id_or_name (Integer, String, nil) (defaults to: nil)

    The Key's id or name value if a kind was provided in the first parameter.

  • consistency (Symbol) (defaults to: nil)

    The non-transactional read consistency to use. Cannot be set to :strong for global queries. Accepted values are :eventual and :strong.

    The default consistency depends on the type of lookup used. See Eventual Consistency in Google Cloud Datastore for more information.

  • read_time (Time) (defaults to: nil)

    Reads entities as they were at the given time. This may not be older than 270 seconds. Optional

Returns:



360
361
362
363
364
365
366
# File 'lib/google/cloud/datastore/dataset.rb', line 360

def find key_or_kind, id_or_name = nil, consistency: nil, read_time: nil
  key = key_or_kind
  unless key.is_a? Google::Cloud::Datastore::Key
    key = Key.new key_or_kind, id_or_name
  end
  find_all(key, consistency: consistency, read_time: read_time).first
end

#find_all(*keys, consistency: nil, read_time: nil) ⇒ Google::Cloud::Datastore::Dataset::LookupResults Also known as: lookup

Retrieve the entities for the provided keys. The order of results is undefined and has no relation to the order of keys arguments.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task_key1 = datastore.key "Task", "sampleTask1"
task_key2 = datastore.key "Task", "sampleTask2"
tasks = datastore.find_all task_key1, task_key2

Parameters:

  • keys (Key)

    One or more Key objects to find records for.

  • consistency (Symbol) (defaults to: nil)

    The non-transactional read consistency to use. Cannot be set to :strong for global queries. Accepted values are :eventual and :strong.

    The default consistency depends on the type of lookup used. See Eventual Consistency in Google Cloud Datastore for more information.

  • read_time (Time) (defaults to: nil)

    Reads entities as they were at the given time. This may not be older than 270 seconds. Optional

Returns:



396
397
398
399
400
401
402
# File 'lib/google/cloud/datastore/dataset.rb', line 396

def find_all *keys, consistency: nil, read_time: nil
  ensure_service!
  check_consistency! consistency
  lookup_res = service.lookup(*Array(keys).flatten.map(&:to_grpc),
                              consistency: consistency, read_time: read_time)
  LookupResults.from_grpc lookup_res, service, consistency, nil, read_time
end

#gql(query, bindings = {}) ⇒ Google::Cloud::Datastore::GqlQuery

Create a new GqlQuery instance. This is a convenience method to make the creation of GqlQuery objects easier.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

gql_query = datastore.gql "SELECT * FROM Task WHERE done = @done",
                          done: false
tasks = datastore.run gql_query

The previous example is equivalent to:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

gql_query = Google::Cloud::Datastore::GqlQuery.new
gql_query.query_string = "SELECT * FROM Task WHERE done = @done"
gql_query.named_bindings = {done: false}
tasks = datastore.run gql_query

Parameters:

  • query (String)

    The GQL query string.

  • bindings (Hash) (defaults to: {})

    Named bindings for the GQL query string, each key must match regex [A-Za-z_$][A-Za-z_$0-9]*, must not match regex __.*__, and must not be "". The value must be an Object that can be stored as an Entity property value, or a Cursor.

Returns:



870
871
872
873
874
875
# File 'lib/google/cloud/datastore/dataset.rb', line 870

def gql query, bindings = {}
  gql = GqlQuery.new
  gql.query_string = query
  gql.named_bindings = bindings unless bindings.empty?
  gql
end

#insert(*entities) ⇒ Array<Google::Cloud::Datastore::Entity>

Insert one or more entities to the Datastore. An InvalidArgumentError will raised if the entities cannot be inserted.

Examples:

Insert a new entity:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task = datastore.entity "Task" do |t|
  t["type"] = "Personal"
  t["done"] = false
  t["priority"] = 4
  t["description"] = "Learn Cloud Datastore"
end
task.key.id #=> nil
datastore.insert task
task.key.id #=> 123456

Insert multiple new entities in a batch:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task1 = datastore.entity "Task" do |t|
  t["type"] = "Personal"
  t["done"] = false
  t["priority"] = 4
  t["description"] = "Learn Cloud Datastore"
end

task2 = datastore.entity "Task" do |t|
  t["type"] = "Personal"
  t["done"] = false
  t["priority"] = 5
  t["description"] = "Integrate Cloud Datastore"
end

task_key1, task_key2 = datastore.insert(task1, task2).map(&:key)

Parameters:

  • entities (Entity)

    One or more entity objects to be inserted.

Returns:



235
236
237
# File 'lib/google/cloud/datastore/dataset.rb', line 235

def insert *entities
  commit { |c| c.insert(*entities) }
end

#key(*path, project: nil, namespace: nil) ⇒ Google::Cloud::Datastore::Key

Create a new Key instance. This is a convenience method to make the creation of Key objects easier.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task_key = datastore.key "Task", "sampleTask"

The previous example is equivalent to:

require "google/cloud/datastore"

task_key = Google::Cloud::Datastore::Key.new "Task", "sampleTask"

Create an empty key:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

key = datastore.key

Create an incomplete key:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

key = datastore.key "User"

Create a key with a parent:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

key = datastore.key [["TaskList", "default"],
                     ["Task", "sampleTask"]]
key.path #=> [["TaskList", "default"], ["Task", "sampleTask"]]

Create a key with multi-level ancestry:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

key = datastore.key([
  ["User", "alice"],
  ["TaskList", "default"],
  ["Task", "sampleTask"]
])
key.path.count #=> 3
key.path[0] #=> ["User", "alice"]
key.path[1] #=> ["TaskList", "default"]
key.path[2] #=> ["Task", "sampleTask"]

Create an incomplete key with a parent:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

key = datastore.key "TaskList", "default", "Task"
key.path #=> [["TaskList", "default"], ["Task", nil]]

Create a key with a project and namespace:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

key = datastore.key ["TaskList", "default"], ["Task", "sampleTask"],
                    project: "my-todo-project",
                    namespace: "example-ns"
key.path #=> [["TaskList", "default"], ["Task", "sampleTask"]]
key.project #=> "my-todo-project"
key.namespace #=> "example-ns"

Parameters:

  • path (Array<Array(String,(String|Integer|nil))>)

    An optional list of pairs for the key's path. Each pair may include the key's kind (String) and an id (Integer) or name (String). This is optional.

  • project (String) (defaults to: nil)

    The project of the Key. This is optional.

  • namespace (String) (defaults to: nil)

    namespace kind of the Key. This is optional.

Returns:



960
961
962
963
964
965
966
967
968
969
970
# File 'lib/google/cloud/datastore/dataset.rb', line 960

def key *path, project: nil, namespace: nil
  path = path.flatten.each_slice(2).to_a # group in pairs
  kind, id_or_name = path.pop
  Key.new(kind, id_or_name).tap do |k|
    k.project = project
    k.namespace = namespace
    unless path.empty?
      k.parent = key path, project: project, namespace: namespace
    end
  end
end

#project_idObject Also known as: project

The Datastore project connected to.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new(
  project_id: "my-todo-project",
  credentials: "/path/to/keyfile.json"
)

datastore.project_id #=> "my-todo-project"


82
83
84
# File 'lib/google/cloud/datastore/dataset.rb', line 82

def project_id
  service.project
end

#query(*kinds) ⇒ Google::Cloud::Datastore::Query

Create a new Query instance. This is a convenience method to make the creation of Query objects easier.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query("Task").
  where("done", "=", false)
tasks = datastore.run query

The previous example is equivalent to:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = Google::Cloud::Datastore::Query.new.
  kind("Task").
  where("done", "=", false)
tasks = datastore.run query

Parameters:

  • kinds (String)

    The kind of entities to query. This is optional.

Returns:



833
834
835
836
837
# File 'lib/google/cloud/datastore/dataset.rb', line 833

def query *kinds
  query = Query.new
  query.kind(*kinds) unless kinds.empty?
  query
end

#read_only_transaction(read_time: nil) {|tx| ... } ⇒ Object Also known as: snapshot

Creates a read-only transaction that provides a consistent snapshot of Cloud Datastore. This can be useful when multiple reads are needed to render a page or export data that must be consistent.

A read-only transaction cannot modify entities; in return they do not contend with other read-write or read-only transactions. Using a read-only transaction for transactions that only read data will potentially improve throughput.

Read-only single-group transactions never fail due to concurrent modifications, so you don't have to implement retries upon failure. However, multi-entity-group transactions can fail due to concurrent modifications, so these should have retries.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task_list_key = datastore.key "TaskList", "default"
query = datastore.query("Task").
  ancestor(task_list_key)

tasks = nil

datastore.read_only_transaction do |tx|
  task_list = tx.find task_list_key
  if task_list
    tasks = tx.run query
  end
end

Parameters:

  • read_time (Time) (defaults to: nil)

    Reads entities at the given time. This may not be older than 60 seconds. Optional

Yields:

  • (tx)

    a block yielding a new transaction

Yield Parameters:

See Also:



787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
# File 'lib/google/cloud/datastore/dataset.rb', line 787

def read_only_transaction read_time: nil
  tx = ReadOnlyTransaction.new service, read_time: read_time
  return tx unless block_given?

  begin
    yield tx
    tx.commit
  rescue StandardError
    begin
      tx.rollback
    rescue StandardError
      raise TransactionError,
            "Transaction failed to commit and rollback."
    end
    raise TransactionError, "Transaction failed to commit."
  end
end

#run(query, namespace: nil, consistency: nil, read_time: nil, explain_options: nil) ⇒ Google::Cloud::Datastore::Dataset::QueryResults Also known as: run_query

Retrieve entities specified by a Query.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query("Task").
  where("done", "=", false)
tasks = datastore.run query

Run an ancestor query with eventual consistency:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task_list_key = datastore.key "TaskList", "default"
query = datastore.query.kind("Task").
  ancestor(task_list_key)

tasks = datastore.run query, consistency: :eventual

Run the query within a namespace with the namespace option:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query("Task").
  where("done", "=", false)
tasks = datastore.run query, namespace: "example-ns"

Run the query with a GQL string.

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

gql_query = datastore.gql "SELECT * FROM Task WHERE done = @done",
                          done: false
tasks = datastore.run gql_query

Run the GQL query within a namespace with namespace option:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

gql_query = datastore.gql "SELECT * FROM Task WHERE done = @done",
                          done: false
tasks = datastore.run gql_query, namespace: "example-ns"

Run the query with explain options to get query plan and execution statistics.

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query("Task")
results = datastore.run query, explain_options: { analyze: true }

# The explain_metrics are available on the results object only after
# all results have been retrieved. You must iterate through all
# pages of results to get the metrics.
all_tasks = []
loop do
  results.each { |task| all_tasks << task }
  break unless results.next?
  results = results.next
end

# The `results` object now holds the last page of results,
# and contains the explain_metrics.
if results.explain_metrics
  stats = results.explain_metrics.execution_stats
  puts "Results returned: #{stats.results_returned}"
  puts "Read operations: #{stats.read_operations}"
end

Run the query with explain options using a Google::Cloud::Datastore::V1::ExplainOptions object.

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query("Task")
explain_options = Google::Cloud::Datastore::V1::ExplainOptions.new
results = datastore.run query, explain_options: explain_options

# You must iterate through all pages of results to get the metrics.
loop do
  break unless results.next?
  results = results.next
end

if results.explain_metrics
  stats = results.explain_metrics.execution_stats
  puts "Read operations: #{stats.read_operations}"
end

Parameters:

  • query (Query, GqlQuery)

    The object with the search criteria.

  • namespace (String) (defaults to: nil)

    The namespace the query is to run within.

  • consistency (Symbol) (defaults to: nil)

    The non-transactional read consistency to use. Cannot be set to :strong for global queries. Accepted values are :eventual and :strong.

    The default consistency depends on the type of query used. See Eventual Consistency in Google Cloud Datastore for more information.

  • read_time (Time) (defaults to: nil)

    Reads entities as they were at the given time. This may not be older than 270 seconds. Optional.

  • explain_options (Hash, Google::Cloud::Datastore::V1::ExplainOptions) (defaults to: nil)

    The options for query explanation. Provide this argument to enable explain metrics. If this argument is left unset, the results will not include explain metrics. See V1::ExplainOptions for details. Optional.

Returns:



520
521
522
523
524
525
526
527
528
529
530
531
532
533
# File 'lib/google/cloud/datastore/dataset.rb', line 520

def run query, namespace: nil, consistency: nil, read_time: nil, explain_options: nil
  ensure_service!
  unless query.is_a?(Query) || query.is_a?(GqlQuery)
    raise ArgumentError, "Cannot run a #{query.class} object."
  end
  check_consistency! consistency

  query_res = service.run_query query.to_grpc, namespace,
                                consistency: consistency, read_time: read_time,
                                explain_options: explain_options

  QueryResults.from_grpc query_res, service, namespace,
                         query.to_grpc.dup, read_time, explain_options
end

#run_aggregation(aggregate_query, namespace: nil, consistency: nil, read_time: nil, explain_options: nil) ⇒ Google::Cloud::Datastore::Dataset::AggregateQueryResults

Retrieve aggregate results specified by an AggregateQuery.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query("Task")
                 .where("done", "=", false)

aggregate_query = query.aggregate_query

res = datastore.run_aggregation aggregate_query

Run an aggregate ancestor query with eventual consistency:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task_list_key = datastore.key "TaskList", "default"
query = datastore.query.kind("Task")
                 .ancestor(task_list_key)

aggregate_query = query.aggregate_query

res = datastore.run_aggregation aggregate_query, consistency: :eventual

Run the aggregate query within a namespace with the namespace option:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query("Task")
                 .where("done", "=", false)

aggregate_query = query.aggregate_query

res = datastore.run_aggregation aggregate_query, namespace: "example-ns"

Run the aggregate query with a GQL string.

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

gql_query = datastore.gql "SELECT COUNT(*) FROM Task WHERE done = @done",
                          done: false
res = datastore.run_aggregation gql_query

Run the aggregate GQL query within a namespace with namespace option:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

gql_query = datastore.gql "SELECT COUNT(*) FROM Task WHERE done = @done",
                          done: false
res = datastore.run_aggregation gql_query, namespace: "example-ns"

Run the aggregate query with explain options to get query plan and execution statistics.

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query("Task")
aggregate_query = query.aggregate_query.add_count aggregate_alias: "total"
results = datastore.run_aggregation aggregate_query, explain_options: { analyze: true }

if results.explain_metrics
  stats = results.explain_metrics.execution_stats
  puts "Read operations: #{stats.read_operations}"
end

Parameters:

  • aggregate_query (AggregateQuery, GqlQuery)

    The object with the aggregate criteria.

  • namespace (String) (defaults to: nil)

    The namespace the query is to run within.

  • consistency (Symbol) (defaults to: nil)

    The non-transactional read consistency to use. Cannot be set to :strong for global queries. Accepted values are :eventual and :strong.

  • read_time (Time) (defaults to: nil)

    Reads entities as they were at the given time. This may not be older than 270 seconds. Optional

    The default consistency depends on the type of query used. See Eventual Consistency in Google Cloud Datastore for more information.

  • explain_options (Hash, Google::Cloud::Datastore::V1::ExplainOptions) (defaults to: nil)

    The options for query explanation. Provide this argument to enable explain metrics. If this argument is left unset, the results will not include explain metrics. See V1::ExplainOptions for details. Optional.

Returns:



628
629
630
631
632
633
634
635
636
637
638
639
640
# File 'lib/google/cloud/datastore/dataset.rb', line 628

def run_aggregation aggregate_query, namespace: nil, consistency: nil, read_time: nil, explain_options: nil
  ensure_service!
  unless aggregate_query.is_a?(AggregateQuery) || aggregate_query.is_a?(GqlQuery)
    raise ArgumentError, "Cannot run a #{aggregate_query.class} object."
  end
  check_consistency! consistency
  aggregate_query_res = service.run_aggregation_query aggregate_query.to_grpc, namespace,
                                                      consistency: consistency,
                                                      read_time: read_time,
                                                      explain_options: explain_options

  AggregateQueryResults.from_grpc aggregate_query_res, explain_options
end

#save(*entities) ⇒ Array<Google::Cloud::Datastore::Entity> Also known as: upsert

Persist one or more entities to the Datastore.

Examples:

Insert a new entity:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task = datastore.entity "Task" do |t|
  t["type"] = "Personal"
  t["done"] = false
  t["priority"] = 4
  t["description"] = "Learn Cloud Datastore"
end
task.key.id #=> nil
datastore.save task
task.key.id #=> 123456

Insert multiple new entities in a batch:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task1 = datastore.entity "Task" do |t|
  t["type"] = "Personal"
  t["done"] = false
  t["priority"] = 4
  t["description"] = "Learn Cloud Datastore"
end

task2 = datastore.entity "Task" do |t|
  t["type"] = "Personal"
  t["done"] = false
  t["priority"] = 5
  t["description"] = "Integrate Cloud Datastore"
end

task_key1, task_key2 = datastore.save(task1, task2).map(&:key)

Update an existing entity:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task = datastore.find "Task", "sampleTask"
task["priority"] = 5
datastore.save task

Parameters:

  • entities (Entity)

    One or more entity objects to be saved.

Returns:



186
187
188
# File 'lib/google/cloud/datastore/dataset.rb', line 186

def save *entities
  commit { |c| c.save(*entities) }
end

#transaction(deadline: nil, previous_transaction: nil) {|tx| ... } ⇒ Object

Creates a Datastore Transaction.

Transactions using the block syntax are committed upon block completion and are automatically retried when known errors are raised during commit. All other errors will be passed on.

All changes are accumulated in memory until the block completes. Transactions will be automatically retried when possible, until deadline is reached. This operation makes separate API requests to begin and commit the transaction.

Examples:

Runs the given block in a database transaction:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task = datastore.entity "Task", "sampleTask" do |t|
  t["type"] = "Personal"
  t["done"] = false
  t["priority"] = 4
  t["description"] = "Learn Cloud Datastore"
end

datastore.transaction do |tx|
  if tx.find(task.key).nil?
    tx.save task
  end
end

If no block is given, a Transaction object is returned:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task = datastore.entity "Task", "sampleTask" do |t|
  t["type"] = "Personal"
  t["done"] = false
  t["priority"] = 4
  t["description"] = "Learn Cloud Datastore"
end

tx = datastore.transaction
begin
  if tx.find(task.key).nil?
    tx.save task
  end
  tx.commit
rescue
  tx.rollback
end

Parameters:

  • deadline (Numeric) (defaults to: nil)

    The total amount of time in seconds the transaction has to succeed. The default is 60.

  • previous_transaction (String) (defaults to: nil)

    The transaction identifier of a transaction that is being retried. Read-write transactions may fail due to contention. A read-write transaction can be retried by specifying previous_transaction when creating the new transaction.

    Specifying previous_transaction provides information that can be used to improve throughput. In particular, if transactional operations A and B conflict, specifying the previous_transaction can help to prevent livelock. (See Transaction#id)

Yields:

  • (tx)

    a block yielding a new transaction

Yield Parameters:

See Also:



712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
# File 'lib/google/cloud/datastore/dataset.rb', line 712

def transaction deadline: nil, previous_transaction: nil
  deadline = validate_deadline deadline
  backoff = 1.0
  start_time = Time.now

  tx = Transaction.new \
    service, previous_transaction: previous_transaction
  return tx unless block_given?

  begin
    yield tx
    tx.commit
  rescue Google::Cloud::UnavailableError => e
    # Re-raise if deadline has passed
    raise e if Time.now - start_time > deadline

    # Sleep with incremental backoff
    sleep backoff *= 1.3

    # Create new transaction and retry the block
    tx = Transaction.new service, previous_transaction: tx.id
    retry
  rescue StandardError
    begin
      tx.rollback
    rescue StandardError
      raise TransactionError,
            "Transaction failed to commit and rollback."
    end
    raise TransactionError, "Transaction failed to commit."
  end
end

#update(*entities) ⇒ Array<Google::Cloud::Datastore::Entity>

Update one or more entities to the Datastore. An InvalidArgumentError will raised if the entities cannot be updated.

Examples:

Update an existing entity:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

task = datastore.find "Task", "sampleTask"
task["done"] = true
datastore.save task

Update multiple new entities in a batch:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query("Task").where("done", "=", false)
tasks = datastore.run query
tasks.each { |t| t["done"] = true }
datastore.update tasks

Parameters:

  • entities (Entity)

    One or more entity objects to be updated.

Returns:



266
267
268
# File 'lib/google/cloud/datastore/dataset.rb', line 266

def update *entities
  commit { |c| c.update(*entities) }
end