Class: Mongoid::Criteria
- Includes:
- Enumerable
- Defined in:
- lib/mongoid/criteria.rb
Overview
The Criteria
class is the core object needed in Mongoid to retrieve objects from the database. It is a DSL that essentially sets up the selector and options arguments that get passed on to a Mongo::Collection
in the Ruby driver. Each method on the Criteria
returns self to they can be chained in order to create a readable criterion to be executed against the database.
Example setup:
criteria = Criteria.new
criteria.only(:field).where(:field => "value").skip(20).limit(20)
criteria.execute
Constant Summary collapse
- AGGREGATE_REDUCE =
"function(obj, prev) { prev.count++; }"
- GROUP_REDUCE =
"function(obj, prev) { prev.group.push(obj); }"
Instance Attribute Summary collapse
-
#klass ⇒ Object
readonly
Returns the value of attribute klass.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
-
#selector ⇒ Object
readonly
Returns the value of attribute selector.
Class Method Summary collapse
-
.translate(*args) ⇒ Object
Translate the supplied arguments into a
Criteria
object.
Instance Method Summary collapse
-
#==(other) ⇒ Object
Returns true if the supplied
Enumerable
orCriteria
is equal to the results of thisCriteria
or the criteria itself. -
#aggregate(klass = nil) ⇒ Object
Aggregate the criteria.
-
#all(attributes = {}) ⇒ Object
Adds a criterion to the
Criteria
that specifies values that must all be matched in order to return results. -
#and(selector = nil) ⇒ Object
Adds a criterion to the
Criteria
that specifies values that must be matched in order to return results. -
#count ⇒ Object
Get the count of matching documents in the database for the
Criteria
. -
#each(&block) ⇒ Object
Iterate over each
Document
in the results. -
#excludes(attributes = {}) ⇒ Object
Adds a criterion to the
Criteria
that specifies values that are not allowed to match any document in the database. -
#extras(extras) ⇒ Object
Adds a criterion to the
Criteria
that specifies additional options to be passed to the Ruby driver, in the exact format for the driver. -
#group ⇒ Object
Groups the criteria.
-
#id(object_id) ⇒ Object
Adds a criterion to the
Criteria
that specifies an id that must be matched. -
#in(attributes = {}) ⇒ Object
Adds a criterion to the
Criteria
that specifies values where any can be matched in order to return results. -
#initialize(klass) ⇒ Criteria
constructor
Create the new
Criteria
object. -
#last ⇒ Object
Return the last result for the
Criteria
. -
#limit(value = 20) ⇒ Object
Adds a criterion to the
Criteria
that specifies the maximum number of results to return. -
#merge(other) ⇒ Object
Merges another object into this
Criteria
. -
#method_missing(name, *args) ⇒ Object
Used for chaining
Criteria
scopes together in the for of class methods on theDocument
the criteria is for. -
#not_in(exclusions) ⇒ Object
Adds a criterion to the
Criteria
that specifies values where none should match in order to return results. -
#offset ⇒ Object
Returns the offset option.
-
#one ⇒ Object
(also: #first)
Return the first result for the
Criteria
. -
#only(*args) ⇒ Object
Adds a criterion to the
Criteria
that specifies the fields that will get returned from the Document. -
#order_by(params = []) ⇒ Object
Adds a criterion to the
Criteria
that specifies the sort order of the returned documents in the database. -
#page ⇒ Object
Either returns the page option and removes it from the options, or returns a default value of 1.
-
#paginate ⇒ Object
Executes the
Criteria
and paginates the results. -
#per_page ⇒ Object
Returns the number of results per page or the default of 20.
-
#skip(value = 0) ⇒ Object
Adds a criterion to the
Criteria
that specifies how many results to skip when returning Documents. -
#where(selector = nil) ⇒ Object
Adds a criterion to the
Criteria
that specifies values that must be matched in order to return results.
Constructor Details
#initialize(klass) ⇒ Criteria
Create the new Criteria
object. This will initialize the selector and options hashes, as well as the type of criteria.
Options:
type: One of :all, :first:, or :last klass: The class to execute on.
216 217 218 |
# File 'lib/mongoid/criteria.rb', line 216 def initialize(klass) @selector, @options, @klass = { :_type => { "$in" => klass._types } }, {}, klass end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
Used for chaining Criteria
scopes together in the for of class methods on the Document
the criteria is for.
Options:
name: The name of the class method on the Document
to chain. args: The arguments passed to the method.
Example:
class Person < Mongoid::Document
field :title
field :terms, :type => Boolean, :default => false
class << self
def knights
all(:conditions => { :title => "Sir" })
end
def accepted
all(:conditions => { :terms => true })
end
end
end
Person.accepted.knights #returns a merged criteria of the 2 scopes.
Returns: Criteria
297 298 299 300 301 302 303 304 305 |
# File 'lib/mongoid/criteria.rb', line 297 def method_missing(name, *args) if @klass.respond_to?(name) new_scope = @klass.send(name) new_scope.merge(self) return new_scope else return collect.send(name, *args) end end |
Instance Attribute Details
#klass ⇒ Object (readonly)
Returns the value of attribute klass.
20 21 22 |
# File 'lib/mongoid/criteria.rb', line 20 def klass @klass end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
20 21 22 |
# File 'lib/mongoid/criteria.rb', line 20 def @options end |
#selector ⇒ Object (readonly)
Returns the value of attribute selector.
20 21 22 |
# File 'lib/mongoid/criteria.rb', line 20 def selector @selector end |
Class Method Details
.translate(*args) ⇒ Object
Translate the supplied arguments into a Criteria
object.
If the passed in args is a single String
, then it will construct an id Criteria
from it.
If the passed in args are a type and a hash, then it will construct the Criteria
with the proper selector, options, and type.
Options:
args: either a String
or a Symbol
, +Hash combination.
Example:
Criteria.translate(Person, "4ab2bc4b8ad548971900005c")
Criteria.translate(Person, :conditions => { :field => "value"}, :limit => 20)
Returns a new Criteria
object.
440 441 442 443 444 445 446 447 448 449 450 451 |
# File 'lib/mongoid/criteria.rb', line 440 def self.translate(*args) klass = args[0] params = args[1] || {} if params.is_a?(String) document = new(klass).id(params).one if Mongoid.raise_not_found_error raise Errors::DocumentNotFound.new(klass, params) unless document end return document end return new(klass).where(params.delete(:conditions) || {}).extras(params) end |
Instance Method Details
#==(other) ⇒ Object
Returns true if the supplied Enumerable
or Criteria
is equal to the results of this Criteria
or the criteria itself.
This will force a database load when called if an enumerable is passed.
Options:
other: The other Enumerable
or Criteria
to compare to.
30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/mongoid/criteria.rb', line 30 def ==(other) case other when Criteria self.selector == other.selector && self. == other. when Enumerable @collection ||= execute return (@collection == other) else return false end end |
#aggregate(klass = nil) ⇒ Object
Aggregate the criteria. This will take the internally built selector and options and pass them on to the Ruby driver’s group() method on the collection. The collection itself will be retrieved from the class provided, and once the query has returned it will provided a grouping of keys with counts.
Example:
criteria.select(:field1).where(:field1 => "Title").aggregate(Person)
51 52 53 54 |
# File 'lib/mongoid/criteria.rb', line 51 def aggregate(klass = nil) @klass = klass if klass @klass.collection.group(@options[:fields], @selector, { :count => 0 }, AGGREGATE_REDUCE) end |
#all(attributes = {}) ⇒ Object
Adds a criterion to the Criteria
that specifies values that must all be matched in order to return results. Similar to an “in” clause but the underlying conditional logic is an “AND” and not an “OR”. The MongoDB conditional operator that will be used is “$all”.
Options:
attributes: A Hash
where the key is the field name and the value is an Array
of values that must all match.
Example:
criteria.all(:field => ["value1", "value2"])
criteria.all(:field1 => ["value1", "value2"], :field2 => ["value1"])
Returns: self
73 74 75 |
# File 'lib/mongoid/criteria.rb', line 73 def all(attributes = {}) update_selector(attributes, "$all") end |
#and(selector = nil) ⇒ Object
Adds a criterion to the Criteria
that specifies values that must be matched in order to return results. This is similar to a SQL “WHERE” clause. This is the actual selector that will be provided to MongoDB, similar to the Javascript object that is used when performing a find() in the MongoDB console.
Options:
selectior: A Hash
that must match the attributes of the Document
.
Example:
criteria.and(:field1 => "value1", :field2 => 15)
Returns: self
92 93 94 |
# File 'lib/mongoid/criteria.rb', line 92 def and(selector = nil) where(selector) end |
#count ⇒ Object
Get the count of matching documents in the database for the Criteria
.
Example:
criteria.count
Returns: Integer
103 104 105 |
# File 'lib/mongoid/criteria.rb', line 103 def count @count ||= @klass.collection.find(@selector, @options.dup).count end |
#each(&block) ⇒ Object
Iterate over each Document
in the results. This can take an optional block to pass to each argument in the results.
Example:
criteria.each { |doc| p doc }
113 114 115 116 |
# File 'lib/mongoid/criteria.rb', line 113 def each(&block) @collection ||= execute block_given? ? @collection.each { |doc| yield doc } : self end |
#excludes(attributes = {}) ⇒ Object
Adds a criterion to the Criteria
that specifies values that are not allowed to match any document in the database. The MongoDB conditional operator that will be used is “$ne”.
Options:
attributes: A Hash
where the key is the field name and the value is a value that must not be equal to the corresponding field value in the database.
Example:
criteria.excludes(:field => "value1")
criteria.excludes(:field1 => "value1", :field2 => "value1")
Returns: self
134 135 136 |
# File 'lib/mongoid/criteria.rb', line 134 def excludes(attributes = {}) update_selector(attributes, "$ne") end |
#extras(extras) ⇒ Object
Adds a criterion to the Criteria
that specifies additional options to be passed to the Ruby driver, in the exact format for the driver.
Options:
extras: A Hash
that gets set to the driver options.
Example:
criteria.extras(:limit => 20, :skip => 40)
Returns: self
150 151 152 |
# File 'lib/mongoid/criteria.rb', line 150 def extras(extras) @options = extras; ; self end |
#group ⇒ Object
Groups the criteria. This will take the internally built selector and options and pass them on to the Ruby driver’s group() method on the collection. The collection itself will be retrieved from the class provided, and once the query has returned it will provided a grouping of keys with objects.
Example:
criteria.select(:field1).where(:field1 => "Title").group(Person)
163 164 165 166 167 168 169 170 171 172 |
# File 'lib/mongoid/criteria.rb', line 163 def group @klass.collection.group( @options[:fields], @selector, { :group => [] }, GROUP_REDUCE ).collect do |docs| docs["group"] = docs["group"].collect { |attrs| @klass.instantiate(attrs) }; docs end end |
#id(object_id) ⇒ Object
Adds a criterion to the Criteria
that specifies an id that must be matched.
Options:
object_id: A String
representation of a Mongo::ObjectID
Example:
criteria.id("4ab2bc4b8ad548971900005c")
Returns: self
205 206 207 |
# File 'lib/mongoid/criteria.rb', line 205 def id(object_id) @selector[:_id] = object_id; self end |
#in(attributes = {}) ⇒ Object
Adds a criterion to the Criteria
that specifies values where any can be matched in order to return results. This is similar to an SQL “IN” clause. The MongoDB conditional operator that will be used is “$in”.
Options:
attributes: A Hash
where the key is the field name and the value is an Array
of values that any can match.
Example:
criteria.in(:field => ["value1", "value2"])
criteria.in(:field1 => ["value1", "value2"], :field2 => ["value1"])
Returns: self
190 191 192 |
# File 'lib/mongoid/criteria.rb', line 190 def in(attributes = {}) update_selector(attributes, "$in") end |
#last ⇒ Object
Return the last result for the Criteria
. Essentially does a find_one on the collection with the sorting reversed. If no sorting parameters have been provided it will default to ids.
Example:
Criteria.select(:name).where(:name = "Chrissy").last
227 228 229 230 231 232 233 234 |
# File 'lib/mongoid/criteria.rb', line 227 def last opts = @options.dup sorting = opts[:sort] sorting = [[:_id, :asc]] unless sorting opts[:sort] = sorting.collect { |option| [ option[0], option[1].invert ] } attributes = @klass.collection.find_one(@selector, opts) attributes ? @klass.instantiate(attributes) : nil end |
#limit(value = 20) ⇒ Object
Adds a criterion to the Criteria
that specifies the maximum number of results to return. This is mostly used in conjunction with skip()
to handle paginated results.
Options:
value: An Integer
specifying the max number of results. Defaults to 20.
Example:
criteria.limit(100)
Returns: self
249 250 251 |
# File 'lib/mongoid/criteria.rb', line 249 def limit(value = 20) @options[:limit] = value; self end |
#merge(other) ⇒ Object
Merges another object into this Criteria
. The other object may be a Criteria
or a Hash
. This is used to combine multiple scopes together, where a chained scope situation may be desired.
Options:
other: The Criteria
or Hash
to merge with.
Example:
criteria.merge({ :conditions => { :title => "Sir" } })
264 265 266 267 |
# File 'lib/mongoid/criteria.rb', line 264 def merge(other) @selector.update(other.selector) @options.update(other.) end |
#not_in(exclusions) ⇒ Object
Adds a criterion to the Criteria
that specifies values where none should match in order to return results. This is similar to an SQL “NOT IN” clause. The MongoDB conditional operator that will be used is “$nin”.
Options:
exclusions: A Hash
where the key is the field name and the value is an Array
of values that none can match.
Example:
criteria.not_in(:field => ["value1", "value2"])
criteria.not_in(:field1 => ["value1", "value2"], :field2 => ["value1"])
Returns: self
323 324 325 |
# File 'lib/mongoid/criteria.rb', line 323 def not_in(exclusions) exclusions.each { |key, value| @selector[key] = { "$nin" => value } }; self end |
#offset ⇒ Object
Returns the offset option. If a per_page option is in the list then it will replace it with a skip parameter and return the same value. Defaults to 20 if nothing was provided.
330 331 332 |
# File 'lib/mongoid/criteria.rb', line 330 def offset @options[:skip] end |
#one ⇒ Object Also known as: first
Return the first result for the Criteria
.
Example:
Criteria.select(:name).where(:name = "Chrissy").one
339 340 341 342 |
# File 'lib/mongoid/criteria.rb', line 339 def one attributes = @klass.collection.find_one(@selector, @options.dup) attributes ? @klass.instantiate(attributes) : nil end |
#only(*args) ⇒ Object
Adds a criterion to the Criteria
that specifies the fields that will get returned from the Document. Used mainly for list views that do not require all fields to be present. This is similar to SQL “SELECT” values.
Options:
args: A list of field names to retrict the returned fields to.
Example:
criteria.only(:field1, :field2, :field3)
Returns: self
359 360 361 |
# File 'lib/mongoid/criteria.rb', line 359 def only(*args) @options[:fields] = args.flatten if args.any?; self end |
#order_by(params = []) ⇒ Object
Adds a criterion to the Criteria
that specifies the sort order of the returned documents in the database. Similar to a SQL “ORDER BY”.
Options:
params: An Array
of [field, direction] sorting pairs.
Example:
criteria.order_by([[:field1, :asc], [:field2, :desc]])
Returns: self
375 376 377 |
# File 'lib/mongoid/criteria.rb', line 375 def order_by(params = []) @options[:sort] = params; self end |
#page ⇒ Object
Either returns the page option and removes it from the options, or returns a default value of 1.
381 382 383 384 |
# File 'lib/mongoid/criteria.rb', line 381 def page skips, limits = @options[:skip], @options[:limit] (skips && limits) ? (skips + limits) / limits : 1 end |
#paginate ⇒ Object
Executes the Criteria
and paginates the results.
Example:
criteria.paginate
391 392 393 394 395 396 |
# File 'lib/mongoid/criteria.rb', line 391 def paginate @collection ||= execute WillPaginate::Collection.create(page, per_page, count) do |pager| pager.replace(@collection) end end |
#per_page ⇒ Object
Returns the number of results per page or the default of 20.
399 400 401 |
# File 'lib/mongoid/criteria.rb', line 399 def per_page (@options[:limit] || 20).to_i end |
#skip(value = 0) ⇒ Object
Adds a criterion to the Criteria
that specifies how many results to skip when returning Documents. This is mostly used in conjunction with limit()
to handle paginated results, and is similar to the traditional “offset” parameter.
Options:
value: An Integer
specifying the number of results to skip. Defaults to 0.
Example:
criteria.skip(20)
Returns: self
417 418 419 |
# File 'lib/mongoid/criteria.rb', line 417 def skip(value = 0) @options[:skip] = value; self end |
#where(selector = nil) ⇒ Object
Adds a criterion to the Criteria
that specifies values that must be matched in order to return results. This is similar to a SQL “WHERE” clause. This is the actual selector that will be provided to MongoDB, similar to the Javascript object that is used when performing a find() in the MongoDB console.
Options:
selectior: A Hash
that must match the attributes of the Document
.
Example:
criteria.where(:field1 => "value1", :field2 => 15)
Returns: self
468 469 470 471 472 473 474 475 476 |
# File 'lib/mongoid/criteria.rb', line 468 def where(selector = nil) case selector when String @selector.update("$where" => selector) else @selector.update(selector ? selector. : {}) end self end |