googleapis / google-cloud-ruby

Google Cloud Client Library for Ruby
https://googleapis.github.io/google-cloud-ruby/
Apache License 2.0
1.36k stars 550 forks source link

Firestore: unexpected results when combining `start_at` or `end_at` with `limit_to_last` in queries #27527

Open sarub0b0 opened 2 weeks ago

sarub0b0 commented 2 weeks ago

When combining start_{at,after} or end_{at,before} with last_to_limit in a Firestore query, start_at and end_at are not applied properly, returning unexpected results.

Environment details

Steps to reproduce

  1. Create documents in the data collection with an id field

        require "google/cloud/firestore"
    
        firestore = Google::Cloud::Firestore.new
    
        10.times do |i|
          doc = firestore.collection("data").doc
          doc.set({ id: i })
        end
  2. Run the sample code using end_before and limit_to_last
  3. An empty array is returned

Code example

# example
require 'google/cloud/firestore'

firestore = Google::Cloud::Firestore.new

col = firestore.col 'data'

query = col.order(:id, :asc).end_before(10).limit_to_last(5)

pp query

docs = query.get

pp docs.map(&:data)

Full backtrace

❯ GOOGLE_CLOUD_PROJECT=PROJECT_ID ruby sample.rb
#<Google::Cloud::Firestore::Query:0x0000000121db92b0
 @client=#<Google::Cloud::Firestore::Client:0x00000001220530e8 @service=Google::Cloud::Firestore::Service(PROJECT_ID)((default))>,
 @limit_type=:last,
 @parent_path="projects/PROJECT_ID/databases/(default)/documents",
 @query=
  <Google::Cloud::Firestore::V1::StructuredQuery: from: [<Google::Cloud::Firestore::V1::StructuredQuery::CollectionSelector: collection_id: "data", all_descendants: false>], order_by: [<Google::Cloud::Firestore::V1::StructuredQuery::Order: field: <Google::Cloud::Firestore::V1::StructuredQuery::FieldReference: field_path: "id">, direction: :DESCENDING>], start_at: <Google::Cloud::Firestore::V1::Cursor: values: [<Google::Cloud::Firestore::V1::Value: integer_value: 10>], before: false>, end_at: <Google::Cloud::Firestore::V1::Cursor: values: [<Google::Cloud::Firestore::V1::Value: integer_value: 10>], before: true>, offset: 0, limit: <Google::Protobuf::Int32Value: value: 5>>>
[]

Expected result

[{:id=>5}, {:id=>6}, {:id=>7}, {:id=>8}, {:id=>9}]

Making sure to follow these steps will guarantee the quickest resolution possible.

Thanks!