diff --git a/CHANGELOG.md b/CHANGELOG.md index 94006e5..a79e0c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ### 2.0.0 (Next) -* [#38](https://github.com/mongoid/mongoid-scroll/pull/38): Allow to reverse the scroll - [@GCorbel](https://github.com/GCorbel). +* [#38](https://github.com/mongoid/mongoid-scroll/pull/38): Add `previous_cursor` - [@GCorbel](https://github.com/GCorbel). +* [#42](https://github.com/mongoid/mongoid-scroll/pull/42): Add `first_cursor` - [@GCorbel](https://github.com/GCorbel). * Your contribution here. ### 1.0.1 (2023/03/15) diff --git a/README.md b/README.md index 6657577..c55fa61 100644 --- a/README.md +++ b/README.md @@ -95,6 +95,8 @@ Feed::Item.desc(:position).limit(5).scroll(saved_iterator.previous_cursor) do |r end ``` +Use `saved_iterator.first_cursor` to loop over the first records. + The iteration finishes when no more records are available. You can also finish iterating over the remaining records by omitting the query limit. ```ruby diff --git a/lib/mongoid/criteria/scrollable/iterator.rb b/lib/mongoid/criteria/scrollable/iterator.rb index fb11b91..8cad507 100644 --- a/lib/mongoid/criteria/scrollable/iterator.rb +++ b/lib/mongoid/criteria/scrollable/iterator.rb @@ -8,6 +8,10 @@ def initialize(previous_cursor:, next_cursor:) @previous_cursor = previous_cursor @next_cursor = next_cursor end + + def first_cursor + @first_cursor ||= next_cursor.class.new(nil, next_cursor.sort_options) + end end end end diff --git a/spec/mongo/collection_view_spec.rb b/spec/mongo/collection_view_spec.rb index 2f329e3..323140e 100644 --- a/spec/mongo/collection_view_spec.rb +++ b/spec/mongo/collection_view_spec.rb @@ -127,6 +127,17 @@ expect(Mongoid.default_client['feed_items'].find.sort(field_name => 1).limit(2).scroll(second_iterator.previous_cursor, field_type: field_type).to_a).to eq(records.limit(2).to_a) expect(Mongoid.default_client['feed_items'].find.sort(field_name => 1).limit(2).scroll(third_iterator.previous_cursor, field_type: field_type).to_a).to eq(records.skip(2).limit(2).to_a) end + it 'can loop over the first records with the first cursor' do + first_cursor = nil + records = Mongoid.default_client['feed_items'].find.sort(field_name => 1) + cursor = cursor_type.from_record records.skip(4).first, field_name: field_name, field_type: field_type, include_current: true + + records.limit(2).scroll(cursor, field_type: field_type) do |_, iterator| + first_cursor = iterator.first_cursor + end + + expect(records.limit(2).scroll(first_cursor, field_type: field_type).to_a).to eq(records.limit(2).to_a) + end end end end diff --git a/spec/mongoid/criteria_spec.rb b/spec/mongoid/criteria_spec.rb index 26e5cd4..53f5cef 100644 --- a/spec/mongoid/criteria_spec.rb +++ b/spec/mongoid/criteria_spec.rb @@ -181,6 +181,15 @@ expect(Feed::Item.asc(field_name).limit(2).scroll(second_iterator.previous_cursor)).to eq(records.limit(2)) expect(Feed::Item.asc(field_name).limit(2).scroll(third_iterator.previous_cursor)).to eq(records.skip(2).limit(2)) end + it 'can loop over the first records with the first page cursor' do + first_cursor = nil + + Feed::Item.asc(field_name).limit(2).scroll(cursor_type) do |_, it| + first_cursor = it.first_cursor + end + + expect(Feed::Item.asc(field_name).limit(2).scroll(first_cursor).to_a).to eq(Feed::Item.asc(field_name).limit(2).to_a) + end end end end