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

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

Overview

QueryResults is a special case Array with additional values. A QueryResults object is returned from Dataset#run and contains the Entities from the query as well as the query's cursor and more_results value.

Please be cautious when treating the QueryResults as an Array. Many common Array methods will return a new Array instance.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query("Task")
tasks = datastore.run query

tasks.size #=> 3
tasks.cursor.to_s #=> "c2Vjb25kLXBhZ2UtY3Vyc29y"

Caution, many Array methods will return a new Array instance:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query("Task")
tasks = datastore.run query

tasks.size #=> 3
tasks.cursor.to_s #=> "c2Vjb25kLXBhZ2UtY3Vyc29y"
descriptions = tasks.map { |t| t["description"] }
descriptions.size #=> 3
descriptions.cursor #=> raise NoMethodError

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#batch_read_timeGoogle::Protobuf::Timestamp

Read timestamp this batch was returned from. This applies to the range of results from the query's start_cursor (or the beginning of the query if no cursor was given) to this batch's end_cursor (not the query's end_cursor).

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. This value will not be set for eventually consistent queries in Cloud Datastore.

Returns:

  • (Google::Protobuf::Timestamp)


88
89
90
# File 'lib/google/cloud/datastore/dataset/query_results.rb', line 88

def batch_read_time
  @batch_read_time
end

#end_cursorGoogle::Cloud::Datastore::Cursor Also known as: cursor

The end_cursor of the QueryResults.



61
62
63
# File 'lib/google/cloud/datastore/dataset/query_results.rb', line 61

def end_cursor
  @end_cursor
end

#explain_metricsGoogle::Cloud::Datastore::V1::ExplainMetrics?

Query explain metrics. This is only present when the [RunQueryRequest.explain_options][google.datastore.v1.RunQueryRequest.explain_options] is provided, and it is sent only once with or after the last QueryResults batch.

To retrieve metrics, iterate over all QueryResults (e.g. with next). The explain_metrics field will be set on final QueryResults object.

Returns:

  • (Google::Cloud::Datastore::V1::ExplainMetrics, nil)


98
99
100
# File 'lib/google/cloud/datastore/dataset/query_results.rb', line 98

def explain_metrics
  @explain_metrics
end

#explain_optionsGoogle::Cloud::Datastore::V1::ExplainOptions?

The options for query explanation.

This is a copy of the input parameter supplied to the Google::Cloud::Datastore::Dataset#run function.

Returns:

  • (Google::Cloud::Datastore::V1::ExplainOptions, nil)


115
116
117
# File 'lib/google/cloud/datastore/dataset/query_results.rb', line 115

def explain_options
  @explain_options
end

#more_resultsSymbol

The state of the query after the current batch.

Expected values are:

  • :NOT_FINISHED
  • :MORE_RESULTS_AFTER_LIMIT
  • :MORE_RESULTS_AFTER_CURSOR
  • :NO_MORE_RESULTS

Returns:

  • (Symbol)


74
75
76
# File 'lib/google/cloud/datastore/dataset/query_results.rb', line 74

def more_results
  @more_results
end

#read_timeTime?

Time at which the entities are being read. This would not be older than 270 seconds.

This is a copy of the input parameter supplied to the Google::Cloud::Datastore::Dataset#run function.

Returns:

  • (Time, nil)


107
108
109
# File 'lib/google/cloud/datastore/dataset/query_results.rb', line 107

def read_time
  @read_time
end

Instance Method Details

#all(request_limit: nil) {|result| ... } ⇒ Enumerator

Retrieves all query results by repeatedly loading #next until #next? returns false. Calls the given block once for each query result, which is passed as the parameter.

An Enumerator is returned if no block is given.

This method may make several API calls until all query results are retrieved. Be sure to use as narrow a search criteria as possible. Please use with caution.

Examples:

Iterating each query result by passing a block:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query "Task"
tasks = datastore.run query
tasks.all do |t|
  puts "Task #{t.key.id} (#cursor)"
end

Using the enumerator by not passing a block:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query "Task"
tasks = datastore.run query
tasks.all.map(&:key).each do |key|
  puts "Key #{key.id}"
end

Limit the number of API calls made:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query "Task"
tasks = datastore.run query
tasks.all(request_limit: 10) do |t|
  puts "Task #{t.key.id} (#cursor)"
end

Parameters:

  • request_limit (Integer) (defaults to: nil)

    The upper limit of API requests to make to load all query results. Default is no limit.

Yields:

  • (result)

    The block for accessing each query result.

Yield Parameters:

  • result (Entity)

    The query result object.

Returns:

  • (Enumerator)


321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
# File 'lib/google/cloud/datastore/dataset/query_results.rb', line 321

def all request_limit: nil, &block
  request_limit = request_limit.to_i if request_limit
  unless block_given?
    return enum_for :all, request_limit: request_limit
  end
  results = self
  loop do
    results.each(&block)
    if request_limit
      request_limit -= 1
      break if request_limit.negative?
    end
    break unless results.next?
    results = results.next
  end
end

#all_with_cursor(request_limit: nil) {|result, cursor| ... } ⇒ Enumerator

Retrieves all query results and cursors by repeatedly loading #next until #next? returns false. Calls the given block once for each result and cursor combination, which are passed as parameters.

An Enumerator is returned if no block is given.

This method may make several API calls until all query results are retrieved. Be sure to use as narrow a search criteria as possible. Please use with caution.

Examples:

Iterating all results and cursors by passing a block:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query "Task"
tasks = datastore.run query
tasks.all_with_cursor do |task, cursor|
  puts "Task #{task.key.id} (#cursor)"
end

Using the enumerator by not passing a block:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query "Task"
tasks = datastore.run query
tasks.all_with_cursor.count # number of result/cursor pairs

Limit the number of API calls made:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query "Task"
tasks = datastore.run query
tasks.all_with_cursor(request_limit: 10) do |task, cursor|
  puts "Task #{task.key.id} (#cursor)"
end

Parameters:

  • request_limit (Integer) (defaults to: nil)

    The upper limit of API requests to make to load all tables. Default is no limit.

Yields:

  • (result, cursor)

    The block for accessing each query result and cursor.

Yield Parameters:

  • result (Entity)

    The query result object.

  • cursor (Cursor)

    The cursor object.

Returns:

  • (Enumerator)


390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
# File 'lib/google/cloud/datastore/dataset/query_results.rb', line 390

def all_with_cursor request_limit: nil, &block
  request_limit = request_limit.to_i if request_limit
  unless block_given?
    return enum_for :all_with_cursor, request_limit: request_limit
  end
  results = self

  loop do
    results.zip(results.cursors).each(&block)
    if request_limit
      request_limit -= 1
      break if request_limit.negative?
    end
    break unless results.next?
    results = results.next
  end
end

#cursor_for(result) ⇒ Cursor

Retrieve the Cursor for the provided result.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query "Task"
tasks = datastore.run query

first_task = tasks.first
first_cursor = tasks.cursor_for first_task

Parameters:

  • result (Entity)

    The entity object to get a cursor for.

Returns:



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

def cursor_for result
  cursor_index = index result
  return nil if cursor_index.nil?
  cursors[cursor_index]
end

#each_with_cursor {|result, cursor| ... } ⇒ Enumerator

Calls the given block once for each result and cursor combination, which are passed as parameters.

An Enumerator is returned if no block is given.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query "Task"
tasks = datastore.run query
tasks.each_with_cursor do |task, cursor|
  puts "Task #{task.key.id} (#cursor)"
end

Yields:

  • (result, cursor)

    The block for accessing each query result and cursor.

Yield Parameters:

  • result (Entity)

    The query result object.

  • cursor (Cursor)

    The cursor object.

Returns:

  • (Enumerator)


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

def each_with_cursor
  return enum_for :each_with_cursor unless block_given?
  zip(cursors).each { |r, c| yield [r, c] }
end

#more_after_cursor?Boolean

Convenience method for determining if the more_results value is :MORE_RESULTS_AFTER_CURSOR

Returns:

  • (Boolean)


144
145
146
# File 'lib/google/cloud/datastore/dataset/query_results.rb', line 144

def more_after_cursor?
  more_results == :MORE_RESULTS_AFTER_CURSOR
end

#more_after_limit?Boolean

Convenience method for determining if the more_results value is :MORE_RESULTS_AFTER_LIMIT

Returns:

  • (Boolean)


137
138
139
# File 'lib/google/cloud/datastore/dataset/query_results.rb', line 137

def more_after_limit?
  more_results == :MORE_RESULTS_AFTER_LIMIT
end

#nextQueryResults

Retrieve the next page of results.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query "Task"
tasks = datastore.run query

if tasks.next?
  next_tasks = tasks.next
end

Returns:



201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/google/cloud/datastore/dataset/query_results.rb', line 201

def next
  return nil unless next?
  return nil if end_cursor.nil?
  ensure_service!
  query.start_cursor = cursor.to_grpc # should always be a Cursor...
  query.offset = 0 # Never carry an offset across batches
  unless query.limit.nil?
    # Reduce the limit by the number of entities returned in the current batch
    query.limit.value -= count
  end
  query_res = service.run_query query, namespace, read_time: read_time, explain_options: explain_options
  self.class.from_grpc query_res, service, namespace, query, read_time, explain_options
end

#next?Boolean

Whether there are more results available.

Examples:

require "google/cloud/datastore"

datastore = Google::Cloud::Datastore.new

query = datastore.query "Task"
tasks = datastore.run query

if tasks.next?
  next_tasks = tasks.next
end

Returns:

  • (Boolean)


178
179
180
# File 'lib/google/cloud/datastore/dataset/query_results.rb', line 178

def next?
  not_finished?
end

#no_more?Boolean

Convenience method for determining if the more_results value is :NO_MORE_RESULTS

Returns:

  • (Boolean)


151
152
153
# File 'lib/google/cloud/datastore/dataset/query_results.rb', line 151

def no_more?
  more_results == :NO_MORE_RESULTS
end

#not_finished?Boolean

Convenience method for determining if the more_results value is :NOT_FINISHED

Returns:

  • (Boolean)


130
131
132
# File 'lib/google/cloud/datastore/dataset/query_results.rb', line 130

def not_finished?
  more_results == :NOT_FINISHED
end