Class: MongoDoc::Criteria
- Includes:
- Enumerable
- Defined in:
- lib/mongodoc/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.select(:field => "value").only(:field).skip(20).limit(20)
criteria.execute
Constant Summary collapse
- SORT_REVERSALS =
{ :asc => :desc, :ascending => :descending, :desc => :asc, :descending => :ascending }
- 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(klass, params = {}) ⇒ 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(use_klass = nil) ⇒ Object
Aggregate the criteria.
-
#count ⇒ Object
Get the count of matching documents in the database for the
Criteria
. -
#each(&block) ⇒ Object
Iterate over each
Document
in the results and pass each document to the block. -
#every(selections = {}) ⇒ Object
Adds a criterion to the
Criteria
that specifies values that must all be matched in order to return results. -
#excludes(exclusions = {}) ⇒ 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(use_klass = nil) ⇒ Object
Groups the criteria.
-
#id(object_id) ⇒ Object
Adds a criterion to the
Criteria
that specifies an id that must be matched. -
#in(inclusions = {}) ⇒ 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
. -
#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.
-
#select(*args) ⇒ Object
Adds a criterion to the
Criteria
that specifies the fields that will get returned from the Document. -
#skip(value = 0) ⇒ Object
Adds a criterion to the
Criteria
that specifies how many results to skip when returning Documents. -
#where(add_selector = {}) ⇒ 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.
219 220 221 |
# File 'lib/mongodoc/criteria.rb', line 219 def initialize(klass) @selector, @options, @klass = {}, {}, 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
299 300 301 302 303 |
# File 'lib/mongodoc/criteria.rb', line 299 def method_missing(name, *args) new_scope = klass.send(name) new_scope.merge(self) new_scope end |
Instance Attribute Details
#klass ⇒ Object (readonly)
Returns the value of attribute klass.
28 29 30 |
# File 'lib/mongodoc/criteria.rb', line 28 def klass @klass end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
28 29 30 |
# File 'lib/mongodoc/criteria.rb', line 28 def @options end |
#selector ⇒ Object (readonly)
Returns the value of attribute selector.
28 29 30 |
# File 'lib/mongodoc/criteria.rb', line 28 def selector @selector end |
Class Method Details
.translate(klass, params = {}) ⇒ 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.
429 430 431 432 |
# File 'lib/mongodoc/criteria.rb', line 429 def self.translate(klass, params = {}) return new(klass).id(params).one if params.is_a?(String) 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.
38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/mongodoc/criteria.rb', line 38 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(use_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)
59 60 61 62 |
# File 'lib/mongodoc/criteria.rb', line 59 def aggregate(use_klass = nil) aggregating_klass = use_klass ? use_klass : klass aggregating_klass.collection.group([:fields], selector, { :count => 0 }, AGGREGATE_REDUCE) end |
#count ⇒ Object
Get the count of matching documents in the database for the Criteria
.
Example:
criteria.count
Returns: Integer
92 93 94 |
# File 'lib/mongodoc/criteria.rb', line 92 def count @count ||= klass.collection.find(selector, .dup).count end |
#each(&block) ⇒ Object
Iterate over each Document
in the results and pass each document to the block.
Example:
criteria.each { |doc| p doc }
102 103 104 105 106 107 108 109 |
# File 'lib/mongodoc/criteria.rb', line 102 def each(&block) @collection ||= execute if block_given? @collection.each(&block) else self end end |
#every(selections = {}) ⇒ 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:
selections: A Hash
where the key is the field name and the value is an Array
of values that must all match.
Example:
criteria.every(:field => ["value1", "value2"])
criteria.every(:field1 => ["value1", "value2"], :field2 => ["value1"])
Returns: self
81 82 83 |
# File 'lib/mongodoc/criteria.rb', line 81 def every(selections = {}) selections.each { |key, value| selector[key] = { "$all" => value } }; self end |
#excludes(exclusions = {}) ⇒ 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:
excludes: 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
127 128 129 |
# File 'lib/mongodoc/criteria.rb', line 127 def excludes(exclusions = {}) exclusions.each { |key, value| selector[key] = { "$ne" => value } }; self 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
143 144 145 146 147 |
# File 'lib/mongodoc/criteria.rb', line 143 def extras(extras) .merge!(extras) self end |
#group(use_klass = nil) ⇒ 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)
168 169 170 171 172 173 174 175 |
# File 'lib/mongodoc/criteria.rb', line 168 def group(use_klass = nil) (use_klass || klass).collection.group( [:fields], selector, { :group => [] }, GROUP_REDUCE ).collect {|docs| docs["group"] = MongoDoc::BSON.decode(docs["group"]); docs } 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
208 209 210 |
# File 'lib/mongodoc/criteria.rb', line 208 def id(object_id) selector[:_id] = object_id; self end |
#in(inclusions = {}) ⇒ 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:
inclusions: 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
193 194 195 |
# File 'lib/mongodoc/criteria.rb', line 193 def in(inclusions = {}) inclusions.each { |key, value| selector[key] = { "$in" => value } }; self 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
230 231 232 233 234 235 236 |
# File 'lib/mongodoc/criteria.rb', line 230 def last opts = .dup sorting = opts[:sort] sorting = [[:_id, :asc]] unless sorting opts[:sort] = sorting.collect { |option| [ option.first, Criteria.invert(option.last) ] } klass.collection.find_one(selector, opts) 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
251 252 253 |
# File 'lib/mongodoc/criteria.rb', line 251 def limit(value = 20) [: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" } })
266 267 268 269 |
# File 'lib/mongodoc/criteria.rb', line 266 def merge(other) selector.update(other.selector) .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
321 322 323 |
# File 'lib/mongodoc/criteria.rb', line 321 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.
328 329 330 |
# File 'lib/mongodoc/criteria.rb', line 328 def offset [:skip] end |
#one ⇒ Object Also known as: first
Return the first result for the Criteria
.
Example:
Criteria.select(:name).where(:name = "Chrissy").one
154 155 156 |
# File 'lib/mongodoc/criteria.rb', line 154 def one klass.collection.find_one(selector, .dup) 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
344 345 346 |
# File 'lib/mongodoc/criteria.rb', line 344 def order_by(params = []) [:sort] = params; self end |
#page ⇒ Object
Either returns the page option and removes it from the options, or returns a default value of 1.
350 351 352 353 354 355 356 |
# File 'lib/mongodoc/criteria.rb', line 350 def page if [:skip] && [:limit] ([:skip].to_i + [:limit].to_i) / [:limit].to_i else 1 end end |
#paginate ⇒ Object
Executes the Criteria
and paginates the results.
Example:
criteria.paginate
363 364 365 366 367 368 |
# File 'lib/mongodoc/criteria.rb', line 363 def paginate @collection ||= execute WillPaginate::Collection.create(page, per_page, count) do |pager| pager.replace(@collection.to_a) end end |
#per_page ⇒ Object
Returns the number of results per page or the default of 20.
371 372 373 |
# File 'lib/mongodoc/criteria.rb', line 371 def per_page ([:limit] || 20).to_i end |
#select(*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.select(:field1, :field2, :field3)
Returns: self
388 389 390 |
# File 'lib/mongodoc/criteria.rb', line 388 def select(*args) [:fields] = args.flatten if args.any?; self 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
406 407 408 |
# File 'lib/mongodoc/criteria.rb', line 406 def skip(value = 0) [:skip] = value; self end |
#where(add_selector = {}) ⇒ 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
449 450 451 |
# File 'lib/mongodoc/criteria.rb', line 449 def where(add_selector = {}) selector.merge!(add_selector); self end |