This is an interesting pattern I found using mongoid (3.0.0), which I suspect is a bug.
1.9.3p194 :007 > products = Product.order_by([:_id, :asc ]).limit(5)
=> #<Mongoid::Criteria
selector: {},
options: {:sort=>{"_id"=>1}, :limit=>5},
class: Product,
embedded: false>
1.9.3p194 :008 > products.map(&:_id)
=> ["500fa5614f6d3a23d0000002", "500fa5614f6d3a23d0000003", "500fa5614f6d3a23d0000004", "500fa5614f6d3a23d0000005", "500fa5614f6d3a23d0000006"]
So far so good! However, if I issue the following – I get weird results.
1.9.3p194 :012 > products.count
=> 3654017
This shows me all the product count instead of 5 (since i have :limit => 5)
1.9.3p194 :012 > Product.count
=> 3654017
Now the even more weird part:
1.9.3p194 :010 > products.last
=> #<Product _id: 504952620a5e2323460000aa, _type: nil, ... >
This should have been _id: 500fa5614f6d3a23d0000006. Now, if I try to map the ids again, I get:
1.9.3p194 :019 > products.map(&:id)
=> ["504952620a5e2323460000aa", "504952620a5e2323460000a9", "504952620a5e2323460000a8", "5049524f0a5e2323460000a7", "504950ab0a5e2323460000a6"]
This has changed the criteria entirely! However, I get proper results with this:
1.9.3p194 :008 > products = Product.order_by([:_id, :asc ]).limit(5)
=> #<Mongoid::Criteria
selector: {},
options: {:sort=>{"_id"=>1}, :limit=>5},
class: Product,
embedded: false>
1.9.3p194 :028 > products[0].id
=> "500fa5614f6d3a23d0000002"
1.9.3p194 :029 > products[-1].id
=> "500fa5614f6d3a23d0000006"
This does seem to be related to Mongoid 3.0.0 though. Any ideas?
First keep in Mind that Mongoid has a lazy loading functionnality: the query will be trigerred at the last moment possible.
Let’s dig your issues:
last: it setslimitto-1so it will override your previous setting. To get your expected behavior, you must oblige Mongoid to make the query usingto_a:products = Product.order_by([:_id, :asc ]).limit(5).to_a.lastcount: if you want to respect thelimit, usecount(true)