lib/locomotive/mongoid/patches.rb in locomotive_cms-2.5.4 vs lib/locomotive/mongoid/patches.rb in locomotive_cms-2.5.5
- old
+ new
@@ -20,11 +20,55 @@
attrs
end
end
class Criteria
+ def without_sorting
+ clone.tap { |crit| crit.options.delete(:sort) }
+ end
+
+ # http://code.dblock.org/paging-and-iterating-over-large-mongo-collections
+ def each_by(by, &block)
+ idx = total = 0
+ set_limit = options[:limit]
+ while ((results = ordered_clone.limit(by).skip(idx)) && results.any?)
+ results.each do |result|
+ return self if set_limit and set_limit >= total
+ total += 1
+ yield result
+ end
+ idx += by
+ end
+ self
+ end
+
+ # Optimized version of the max aggregate method.
+ # It works efficiently only if the field is part of a MongoDB index.
+ # more here: http://stackoverflow.com/questions/4762980/getting-the-highest-value-of-a-column-in-mongodb
+ def indexed_max(field)
+ _criteria = criteria.order_by(field.to_sym.desc).only(field.to_sym)
+ selector = _criteria.send(:selector_with_type_selection)
+ fields = _criteria.options[:fields]
+ sort = _criteria.options[:sort]
+
+ document = collection.find(selector).select(fields).sort(sort).limit(1).first
+ document ? document[field.to_s].to_i : nil
+ end
+
def to_liquid
Locomotive::Liquid::Drops::ProxyCollection.new(self)
+ end
+
+ private
+
+ def ordered_clone
+ options[:sort] ? clone : clone.asc(:_id)
+ end
+ end
+
+ module Finders
+ def indexed_max(field)
+ with_default_scope.indexed_max(field)
end
end
module Criterion
class Selector < Hash