The bug of mongoid returning first document when invoking last?
That's not a bug in Mongoid, that's a bug in your expectations of the first
and last
methods. From the fine version 5 manual:
#first ⇒ Document
Note: Mongoid previously added an
_id
sort when no sort parameters were provided explicitly by the user. This caused bad performance issues and was not expected, so#first
/#last
will no longer guarantee order if no sorting parameters are provided. For order guarantees - a sort must be explicitly provided.Get the first document in the database for the criteria's selector.
So first
(as of Mongoid5) gives you the first document in the query with respect to the current order but it no longer supplies a default order. You'll need to supply your own sort
order in the query if you want first
to behave like it used to.
Similarly for last
.
It seems the old behaviour is back in Mongoid 6? - I'm using 6.1.0 and I'm experiencing the following:
t(prod)> Benchmark.measure { Event.where(:created_at => 7.days.ago..1.day.ago).first }=> #<Benchmark::Tms:0x00000003cb00b8 @cstime=0.0, @cutime=0.0, @label="", @real=4.109985898248851, @stime=0.0, @total=0.0, @utime=0.0>t(prod)> Benchmark.measure { Event.where(:created_at => 7.days.ago..1.day.ago).limit(1).entries.first }=> #<Benchmark::Tms:0x000000037377f8 @cstime=0.0, @cutime=0.0, @label="", @real=2.6328365616500378, @stime=0.0, @total=0.0, @utime=0.0>
So using .first instead of .limit(1).entries.first is about twice as slow. One workaround is to do: .first(id_sort: :none)
hope that helps :)