Class: Google::Cloud::Firestore::Query

Inherits:
Object
  • Object
show all
Defined in:
lib/google/cloud/firestore/query.rb

Overview

Query

Represents a query to the Firestore API.

Instances of this class are immutable. All methods that refine the query return new instances.

Examples:

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Create a query
query = firestore.col(:cities).select(:population)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Listen to a query for changes:

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Create a query
query = firestore.col(:cities).order(:population, :desc)

listener = query.listen do |snapshot|
  puts "The query snapshot has #{snapshot.docs.count} documents "
  puts "and has #{snapshot.changes.count} changes."
end

# When ready, stop the listen operation and close the stream.
listener.stop

Direct Known Subclasses

CollectionGroup, CollectionReference

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from_json(json, client) ⇒ Query

Deserializes a JSON text string serialized from this class and returns it as a new instance. See also #to_json.

Examples:

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new
query = firestore.col(:cities).select(:population)

json = query.to_json

new_query = Google::Cloud::Firestore::Query.from_json json, firestore

new_query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Parameters:

Returns:

  • (Query)

    A new query equal to the original query used to create the JSON text string.

Raises:

  • (ArgumentError)


1192
1193
1194
1195
1196
1197
1198
1199
1200
# File 'lib/google/cloud/firestore/query.rb', line 1192

def self.from_json json, client
  raise ArgumentError, "client is required" unless client

  json = JSON.parse json
  query_json = json["query"]
  raise ArgumentError, "Field 'query' is required" unless query_json
  query = Google::Cloud::Firestore::V1::StructuredQuery.decode_json query_json.to_json
  start query, json["parent_path"], client, limit_type: json["limit_type"]&.to_sym
end

Instance Method Details

#aggregate_queryAggregateQuery

Creates an AggregateQuery object for the query.

Examples:

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
query = firestore.col "cities"

# Create an aggregate query
aggregate_query = query.aggregate_query

Returns:



1104
1105
1106
# File 'lib/google/cloud/firestore/query.rb', line 1104

def aggregate_query
  AggregateQuery.new self, parent_path, client
end

#end_at(*values) ⇒ Query

Ends query results at a set of field values. The field values can be specified explicitly as arguments, or can be specified implicitly by providing a DocumentSnapshot object instead. The result set will include the document specified by values.

If the current query already has specified end_before or end_at, this will overwrite it.

The values are associated with the field paths that have been provided to order, and must match the same sort order. An ArgumentError will be raised if more explicit values are given than are present in order.

Examples:

Ending a query at a document reference id

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"
nyc_doc_id = "NYC"

# Create a query
query = cities_col.order(firestore.document_id)
                  .end_at(nyc_doc_id)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Ending a query at a document reference object

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"
nyc_doc_id = "NYC"
nyc_ref = cities_col.doc nyc_doc_id

# Create a query
query = cities_col.order(firestore.document_id)
                  .end_at(nyc_ref)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Ending a query at multiple explicit values

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Create a query
query = cities_col.order(:population, :desc)
                  .order(:name)
                  .end_at(1000000, "New York City")

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Ending a query at a DocumentSnapshot

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Get a document snapshot
nyc_snap = firestore.doc("cities/NYC").get

# Create a query
query = cities_col.order(:population, :desc)
                  .order(:name)
                  .end_at(nyc_snap)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Parameters:

  • values (DocumentSnapshot, Object, Array<Object>)

    The field values to end the query at.

Returns:

  • (Query)

    New query with end_at called on it.

Raises:

  • (ArgumentError)


933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
# File 'lib/google/cloud/firestore/query.rb', line 933

def end_at *values
  raise ArgumentError, "must provide values" if values.empty?

  if limit_type == :last
    raise "cannot call end_at after calling limit_to_last"
  end


  new_query = @query.dup
  new_query ||= StructuredQuery.new

  cursor = values_to_cursor values, new_query
  cursor.before = false
  new_query.end_at = cursor

  start_new_query new_query
end

#end_before(*values) ⇒ Query

Ends query results before a set of field values. The field values can be specified explicitly as arguments, or can be specified implicitly by providing a DocumentSnapshot object instead. The result set will not include the document specified by values.

If the current query already has specified end_before or end_at, this will overwrite it.

The values are associated with the field paths that have been provided to order, and must match the same sort order. An ArgumentError will be raised if more explicit values are given than are present in order.

Examples:

Ending a query before a document reference id

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"
nyc_doc_id = "NYC"

# Create a query
query = cities_col.order(firestore.document_id)
                  .end_before(nyc_doc_id)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Ending a query before a document reference object

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"
nyc_doc_id = "NYC"
nyc_ref = cities_col.doc nyc_doc_id

# Create a query
query = cities_col.order(firestore.document_id)
                  .end_before(nyc_ref)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Ending a query before multiple explicit values

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Create a query
query = cities_col.order(:population, :desc)
                  .order(:name)
                  .end_before(1000000, "New York City")

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Ending a query before a DocumentSnapshot

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Get a document snapshot
nyc_snap = firestore.doc("cities/NYC").get

# Create a query
query = cities_col.order(:population, :desc)
                  .order(:name)
                  .end_before(nyc_snap)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Parameters:

  • values (DocumentSnapshot, Object, Array<Object>)

    The field values to end the query before.

Returns:

  • (Query)

    New query with end_before called on it.

Raises:

  • (ArgumentError)


824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
# File 'lib/google/cloud/firestore/query.rb', line 824

def end_before *values
  raise ArgumentError, "must provide values" if values.empty?

  if limit_type == :last
    raise "cannot call end_before after calling limit_to_last"
  end


  new_query = @query.dup
  new_query ||= StructuredQuery.new

  cursor = values_to_cursor values, new_query
  cursor.before = true
  new_query.end_at = cursor

  start_new_query new_query
end

#explain(read_time: false, analyze: false) ⇒ QueryExplainResult

Retrieves the query explanation for the query. By default the query is only planned, not executed. returning only metrics from the planning stages. If analyze is set to true the query will be planned and executed, returning the full query results alongside both planning and execution stage metrics.

Unlike the Enumerator object that is returned from the Query#get, iterating over QueryExplainResult multiple times will not result in multiple requests to the server. The first set of results will be saved and re-used instead. This is to avoid the situations where the metrics change unpredictably when results are looked at.

Examples:

Iterating over results multiple times

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new
query = firestore.col(:cities).where(:population, :>, 100000)
explanation_result = query.explain analyze: true
results = explanation_result.to_a
results_2 = explanation_result.to_a # same results, no re-query

Getting only the planning stage metrics for the query

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new
query = firestore.col(:cities).where(:population, :>, 100000)

# Get the execution plan without running the query
explain_result = query.explain
metrics = explain_result.explain_metrics
puts "Plan summary: #{metrics.plan_summary}" if metrics&.plan_summary

Getting planning and execution stage metrics, as well as query results

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new
query = firestore.col(:cities).where(:population, :>, 100000)

# Run the query and return metrics from the planning and execution stages
explain_result = query.explain analyze: true
metrics = explain_result.explain_metrics
puts "Plan summary: #{metrics.plan_summary}" if metrics&.plan_summary
puts "Results returned: #{metrics.execution_stats.results_returned}" if metrics&.execution_stats
results = explain_result.to_a

Parameters:

  • read_time (Time) (defaults to: false)

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

  • analyze (Boolean) (defaults to: false)

    Whether to execute the query and return the execution stage metrics in addition to planning metrics. If set to false the query will be planned only and will return planning stage metrics without results. If set to true the query will be executed, and will return the query results, planning stage metrics, and execution stage metrics. Defaults to false.

Returns:



1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
# File 'lib/google/cloud/firestore/query.rb', line 1070

def explain read_time: false, analyze: false
  ensure_service!

  # Validate analyze parameter
  unless [true, false].include? analyze
    raise ArgumentError, "analyze must be a boolean"
  end

  explain_options = ::Google::Cloud::Firestore::V1::ExplainOptions.new
  explain_options.analyze = analyze

  results = service.run_query parent_path, @query, read_time: read_time, explain_options: explain_options

  # Reverse the results for Query#limit_to_last queries since that method reversed the order_by directions.
  results = results.to_a.reverse if limit_type == :last
  QueryExplainResult.new results, client
end

#get(read_time: nil) {|documents| ... } ⇒ Enumerator<DocumentSnapshot> Also known as: run

Retrieves document snapshots for the query.

Examples:

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Create a query
query = cities_col.select(:population)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Get query with read time

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Create a query
query = cities_col.select(:population)

read_time = Time.now

query.get(read_time: read_time) do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Parameters:

  • read_time (Time) (defaults to: nil)

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

Yields:

  • (documents)

    The block for accessing the document snapshots.

Yield Parameters:

Returns:



994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
# File 'lib/google/cloud/firestore/query.rb', line 994

def get read_time: nil
  ensure_service!

  return enum_for :get, read_time: read_time unless block_given?

  results = service.run_query parent_path, @query, read_time: read_time

  # Reverse the results for Query#limit_to_last queries since that method reversed the order_by directions.
  results = results.to_a.reverse if limit_type == :last

  results.each do |result|
    next if result.document.nil?
    yield DocumentSnapshot.from_query_result result, client
  end
end

#limit(num) ⇒ Query

Limits a query to return only the first matching documents.

If the current query already has a limit set, this will overwrite it.

Examples:

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Create a query
query = cities_col.order(:name, :desc).offset(10).limit(5)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Parameters:

  • num (Integer)

    The maximum number of results to return.

Returns:

  • (Query)

    New query with limit called on it.



443
444
445
446
447
448
449
450
451
452
453
454
# File 'lib/google/cloud/firestore/query.rb', line 443

def limit num
  if limit_type == :last
    raise "cannot call limit after calling limit_to_last"
  end

  new_query = @query.dup
  new_query ||= StructuredQuery.new

  new_query.limit = Google::Protobuf::Int32Value.new value: num

  start_new_query new_query, limit_type_override: :first
end

#limit_to_last(num) ⇒ Query

Limits a query to return only the last matching documents.

You must specify at least one "order by" clause for limitToLast queries. (See #order.)

Results for limit_to_last queries are only available once all documents are received. Hence, limit_to_last queries cannot be streamed using #listen.

Examples:

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Create a query
query = cities_col.order(:name, :desc).limit_to_last(5)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Parameters:

  • num (Integer)

    The maximum number of results to return.

Returns:

  • (Query)

    New query with limit_to_last called on it.



485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
# File 'lib/google/cloud/firestore/query.rb', line 485

def limit_to_last num
  new_query = @query.dup

  if new_query.nil? || new_query.order_by.nil? || new_query.order_by.empty?
    raise "specify at least one order clause before calling limit_to_last"
  end

  if limit_type != :last # Don't reverse order_by more than once.
    # Reverse the order_by directions since we want the last results.
    new_query.order_by.each do |order|
      order.direction = order.direction.to_sym == :DESCENDING ? :ASCENDING : :DESCENDING
    end

    # Swap the cursors to match the reversed query ordering.
    new_end_at = new_query.start_at.dup
    new_start_at = new_query.end_at.dup
    if new_end_at
      new_end_at.before = !new_end_at.before
    end
    if new_start_at
      new_start_at.before = !new_start_at.before
    end
    new_query.end_at = new_end_at
    new_query.start_at = new_start_at
  end

  new_query.limit = Google::Protobuf::Int32Value.new value: num

  start_new_query new_query, limit_type_override: :last
end

#listen {|callback| ... } ⇒ QueryListener Also known as: on_snapshot

Listen to this query for changes.

Examples:

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Create a query
query = firestore.col(:cities).order(:population, :desc)

listener = query.listen do |snapshot|
  puts "The query snapshot has #{snapshot.docs.count} documents "
  puts "and has #{snapshot.changes.count} changes."
end

# When ready, stop the listen operation and close the stream.
listener.stop

Yields:

  • (callback)

    The block for accessing the query snapshot.

Yield Parameters:

Returns:

Raises:

  • (ArgumentError)


1132
1133
1134
1135
1136
1137
1138
# File 'lib/google/cloud/firestore/query.rb', line 1132

def listen &callback
  raise ArgumentError, "callback required" if callback.nil?

  ensure_service!

  QueryListener.new(self, &callback).start
end

#offset(num) ⇒ Query

Skips to an offset in a query. If the current query already has specified an offset, this will overwrite it.

Examples:

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Create a query
query = cities_col.limit(5).offset(10)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Parameters:

  • num (Integer)

    The number of results to skip.

Returns:

  • (Query)

    New query with offset called on it.



410
411
412
413
414
415
416
417
# File 'lib/google/cloud/firestore/query.rb', line 410

def offset num
  new_query = @query.dup
  new_query ||= StructuredQuery.new

  new_query.offset = num

  start_new_query new_query
end

#order(field, direction = :asc) ⇒ Query Also known as: order_by

Specifies an "order by" clause on a field.

Examples:

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Create a query
query = cities_col.order(:name)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Order by name descending:

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Create a query
query = cities_col.order(:name, :desc)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Parameters:

  • field (FieldPath, String, Symbol)

    A field path to order results with.

    If a FieldPath object is not provided then the field will be treated as a dotted string, meaning the string represents individual fields joined by ".". Fields containing ~, *, /, [, ], and . cannot be in a dotted string, and should provided using a FieldPath object instead.

  • direction (String, Symbol) (defaults to: :asc)

    The direction to order the results by. Values that start with "a" are considered ascending. Values that start with "d" are considered descending. Default is ascending. Optional.

Returns:

  • (Query)

    New query with order called on it.



366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'lib/google/cloud/firestore/query.rb', line 366

def order field, direction = :asc
  if query_has_cursors? || limit_type == :last
    raise "cannot call order after calling limit_to_last, start_at, start_after, end_before, or end_at"
  end

  new_query = @query.dup
  new_query ||= StructuredQuery.new

  field = FieldPath.parse field unless field.is_a? FieldPath

  new_query.order_by << StructuredQuery::Order.new(
    field:     StructuredQuery::FieldReference.new(
      field_path: field.formatted_string
    ),
    direction: order_direction(direction)
  )

  start_new_query new_query
end

#select(*fields) ⇒ Query

Restricts documents matching the query to return only data for the provided fields.

Examples:

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Create a query
query = cities_col.select(:population)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Parameters:

  • fields (FieldPath, String, Symbol, Array<FieldPath|String|Symbol>)

    A field path to filter results with and return only the specified fields. One or more field paths can be specified.

    If a FieldPath object is not provided then the field will be treated as a dotted string, meaning the string represents individual fields joined by ".". Fields containing ~, *, /, [, ], and . cannot be in a dotted string, and should provided using a FieldPath object instead.

Returns:

  • (Query)

    New query with select called on it.



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/google/cloud/firestore/query.rb', line 128

def select *fields
  new_query = @query.dup
  new_query ||= StructuredQuery.new

  fields = Array(fields).flatten.compact
  fields = [FieldPath.document_id] if fields.empty?
  field_refs = fields.flatten.compact.map do |field|
    field = FieldPath.parse field unless field.is_a? FieldPath
    StructuredQuery::FieldReference.new \
      field_path: field.formatted_string
  end

  new_query.select = StructuredQuery::Projection.new
  field_refs.each do |field_ref|
    new_query.select.fields << field_ref
  end

  start_new_query new_query
end

#start_after(*values) ⇒ Query

Starts query results after a set of field values. The field values can be specified explicitly as arguments, or can be specified implicitly by providing a DocumentSnapshot object instead. The result set will not include the document specified by values.

If the current query already has specified start_at or start_after, this will overwrite it.

The values are associated with the field paths that have been provided to order, and must match the same sort order. An ArgumentError will be raised if more explicit values are given than are present in order.

Examples:

Starting a query after a document reference id

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"
nyc_doc_id = "NYC"

# Create a query
query = cities_col.order(firestore.document_id)
                  .start_after(nyc_doc_id)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Starting a query after a document reference object

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"
nyc_doc_id = "NYC"
nyc_ref = cities_col.doc nyc_doc_id

# Create a query
query = cities_col.order(firestore.document_id)
                  .start_after(nyc_ref)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Starting a query after multiple explicit values

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Create a query
query = cities_col.order(:population, :desc)
                  .order(:name)
                  .start_after(1000000, "New York City")

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Starting a query after a DocumentSnapshot

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Get a document snapshot
nyc_snap = firestore.doc("cities/NYC").get

# Create a query
query = cities_col.order(:population, :desc)
                  .order(:name)
                  .start_after(nyc_snap)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Parameters:

  • values (DocumentSnapshot, Object, Array<Object>)

    The field values to start the query after.

Returns:

  • (Query)

    New query with start_after called on it.

Raises:

  • (ArgumentError)


715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
# File 'lib/google/cloud/firestore/query.rb', line 715

def start_after *values
  raise ArgumentError, "must provide values" if values.empty?

  if limit_type == :last
    raise "cannot call start_after after calling limit_to_last"
  end


  new_query = @query.dup
  new_query ||= StructuredQuery.new

  cursor = values_to_cursor values, new_query
  cursor.before = false
  new_query.start_at = cursor

  start_new_query new_query
end

#start_at(*values) ⇒ Query

Starts query results at a set of field values. The field values can be specified explicitly as arguments, or can be specified implicitly by providing a DocumentSnapshot object instead. The result set will include the document specified by values.

If the current query already has specified start_at or start_after, this will overwrite it.

The values are associated with the field paths that have been provided to order, and must match the same sort order. An ArgumentError will be raised if more explicit values are given than are present in order.

Examples:

Starting a query at a document reference id

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"
nyc_doc_id = "NYC"

# Create a query
query = cities_col.order(firestore.document_id)
                  .start_at(nyc_doc_id)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Starting a query at a document reference object

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"
nyc_doc_id = "NYC"
nyc_ref = cities_col.doc nyc_doc_id

# Create a query
query = cities_col.order(firestore.document_id)
                  .start_at(nyc_ref)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Starting a query at multiple explicit values

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Create a query
query = cities_col.order(:population, :desc)
                  .order(:name)
                  .start_at(1000000, "New York City")

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Starting a query at a DocumentSnapshot

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Get a document snapshot
nyc_snap = firestore.doc("cities/NYC").get

# Create a query
query = cities_col.order(:population, :desc)
                  .order(:name)
                  .start_at(nyc_snap)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Parameters:

  • values (DocumentSnapshot, Object, Array<Object>)

    The field values to start the query at.

Returns:

  • (Query)

    New query with start_at called on it.

Raises:

  • (ArgumentError)


607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
# File 'lib/google/cloud/firestore/query.rb', line 607

def start_at *values
  raise ArgumentError, "must provide values" if values.empty?

  if limit_type == :last
    raise "cannot call start_at after calling limit_to_last"
  end

  new_query = @query.dup
  new_query ||= StructuredQuery.new

  cursor = values_to_cursor values, new_query
  cursor.before = true
  new_query.start_at = cursor

  start_new_query new_query
end

#to_json(options = nil) ⇒ String

Serializes the instance to a JSON text string. See also from_json.

Examples:

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new
query = firestore.col(:cities).select(:population)

json = query.to_json

new_query = Google::Cloud::Firestore::Query.from_json json, firestore

new_query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Returns:

  • (String)

    A JSON text string.



1160
1161
1162
1163
1164
1165
1166
1167
# File 'lib/google/cloud/firestore/query.rb', line 1160

def to_json options = nil
  query_json = Google::Cloud::Firestore::V1::StructuredQuery.encode_json query
  {
    "query" => JSON.parse(query_json),
    "parent_path" => parent_path,
    "limit_type" => limit_type
  }.to_json options
end

#where(filter) ⇒ Query #where(field, operator, value) ⇒ Query

Adds filter to the where clause

@param filter [::Google::Cloud::Firestore::Filter]

Examples:

require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Create a query
query = cities_col.where(:population, :>=, 1000000)

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end
require "google/cloud/firestore"

firestore = Google::Cloud::Firestore.new

# Get a collection reference
cities_col = firestore.col "cities"

# Create a filter
filter = Filter.create(:population, :>=, 1000000)

# Add filter to where clause
query = query.where filter

query.get do |city|
  puts "#{city.document_id} has #{city[:population]} residents."
end

Overloads:

  • #where(filter) ⇒ Query

    Pass Firestore::Filter to where via field_or_filter argument.

  • #where(field, operator, value) ⇒ Query

    Pass arguments to where via positional arguments.

    Parameters:

    • field (FieldPath, String, Symbol)

      A field path to filter results with. If a FieldPath object is not provided then the field will be treated as a dotted string, meaning the string represents individual fields joined by ".". Fields containing ~, *, /, [, ], and . cannot be in a dotted string, and should provided using a FieldPath object instead.

    • operator (String, Symbol)

      The operation to compare the field to. Acceptable values include:

      • less than: <, lt
      • less than or equal: <=, lte
      • greater than: >, gt
      • greater than or equal: >=, gte
      • equal: =, ==, eq, eql, is
      • not equal: !=
      • in: in
      • not in: not-in, not_in
      • array contains: array-contains, array_contains
    • 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:

  • (Query)

    New query with where called on it.



299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'lib/google/cloud/firestore/query.rb', line 299

def where filter_or_field = nil, operator = nil, value = nil
  if query_has_cursors?
    raise "cannot call where after calling " \
          "start_at, start_after, end_before, or end_at"
  end

  new_query = @query.dup
  new_query ||= StructuredQuery.new

  if filter_or_field.is_a? Google::Cloud::Firestore::Filter
    new_query.where = filter_or_field.filter
  else
    new_filter = Google::Cloud::Firestore::Filter.new filter_or_field, operator, value
    add_filters_to_query new_query, new_filter.filter
  end

  start_new_query new_query
end