@@ -11,17 +11,15 @@ def scroll(cursor_or_type = nil, &_block)
11
11
criteria . merge! ( default_sort ) if no_sort_option?
12
12
cursor_options = build_cursor_options ( criteria )
13
13
cursor = cursor . is_a? ( cursor_type ) ? cursor : new_cursor ( cursor_type , cursor , cursor_options )
14
- direction = scroll_direction ( criteria )
15
14
raise_mismatched_sort_fields_error! ( cursor , cursor_options ) if different_sort_fields? ( cursor , cursor_options )
16
- cursor_criteria = build_cursor_criteria ( criteria , cursor )
17
- first_in_page = nil
15
+ records = find_records ( criteria , cursor )
18
16
if block_given?
19
- cursor_criteria . order_by ( _id : direction ) . each do | record |
20
- first_in_page ||= record
21
- yield record , cursor_from_record ( cursor_type , record , cursor_options ) , cursor_from_record ( cursor_type , first_in_page , cursor_options . merge ( previous : true ) )
17
+ first_cursor = cursor_from_record ( cursor_type , records . first , cursor_options . merge ( previous : true ) )
18
+ records . each do | record |
19
+ yield record , cursor_from_record ( cursor_type , record , cursor_options ) , first_cursor
22
20
end
23
21
else
24
- cursor_criteria
22
+ records
25
23
end
26
24
end
27
25
@@ -63,10 +61,21 @@ def new_cursor(cursor_type, cursor, cursor_options)
63
61
cursor_type . new ( cursor , cursor_options )
64
62
end
65
63
66
- def build_cursor_criteria ( criteria , cursor )
64
+ def find_records ( criteria , cursor )
67
65
cursor_criteria = criteria . dup
68
66
cursor_criteria . selector = { '$and' => [ criteria . selector , cursor . criteria ] }
69
- cursor_criteria
67
+ if cursor . previous && criteria . options [ :limit ]
68
+ pipeline = [
69
+ { '$match' => cursor_criteria . selector } ,
70
+ { '$sort' => { cursor . field_name => -cursor . direction } } ,
71
+ { '$limit' => criteria . options [ :limit ] } ,
72
+ { '$sort' => { cursor . field_name => cursor . direction } }
73
+ ]
74
+ aggregation = cursor_criteria . view . aggregate ( pipeline )
75
+ aggregation . map { Mongoid ::Factory . from_db ( cursor_criteria . klass , _1 ) }
76
+ else
77
+ cursor_criteria . order_by ( _id : scroll_direction ( criteria ) )
78
+ end
70
79
end
71
80
72
81
def cursor_from_record ( cursor_type , record , cursor_options )
0 commit comments