Class: Mongoid::Criteria

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Contextual, Mongoid::Criterion::Inspection, Mongoid::Criterion::Scoping, Origin::Queryable
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.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Mongoid::Criterion::Scoping

#apply_default_scope, #remove_scoping, #scoped, #scoped?, #scoping_options, #scoping_options=, #unscoped, #unscoped?, #with_default_scope

Methods included from Mongoid::Criterion::Inspection

#inspect

Methods included from Contextual

#context

Constructor Details

#initialize(klass) ⇒ Criteria

Initialize the new criteria.

Examples:

Init the new criteria.

Criteria.new(Band)

Parameters:

  • klass (Class)

    The model class.

Since:

  • 1.0.0



333
334
335
336
# File 'lib/mongoid/criteria.rb', line 333

def initialize(klass)
  @klass = klass
  super(klass.aliased_fields, klass.fields)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(name, *args, &block) ⇒ Object (private)

Used for chaining Criteria scopes together in the for of class methods on the Document the criteria is for.

Examples:

Handle method missing.

criteria.method_missing(:name)

Parameters:

  • name (Symbol)

    The method name.

  • args (Array)

    The arguments.

Returns:

  • (Object)

    The result of the method call.

Since:

  • 1.0.0



653
654
655
656
657
658
659
660
661
# File 'lib/mongoid/criteria.rb', line 653

def method_missing(name, *args, &block)
  if klass.respond_to?(name)
    klass.send(:with_scope, self) do
      klass.send(name, *args, &block)
    end
  else
    return entries.send(name, *args)
  end
end

Instance Attribute Details

#embeddedObject

Returns the value of attribute embedded.



20
21
22
# File 'lib/mongoid/criteria.rb', line 20

def embedded
  @embedded
end

#klassObject

Returns the value of attribute klass.



20
21
22
# File 'lib/mongoid/criteria.rb', line 20

def klass
  @klass
end

Instance Method Details

#==(other) ⇒ true, false

Note:

This will force a database load when called if an enumerable is passed.

Returns true if the supplied Enumerable or Criteria is equal to the results of this Criteria or the criteria itself.

Parameters:

  • other (Object)

    The other Enumerable or Criteria to compare to.

Returns:

  • (true, false)

    If the objects are equal.

Since:

  • 1.0.0



32
33
34
35
# File 'lib/mongoid/criteria.rb', line 32

def ==(other)
  return super if other.respond_to?(:selector)
  entries == other
end

#as_json(options = nil) ⇒ String

Needed to properly get a criteria back as json

Examples:

Get the criteria as json.

Person.where(:title => "Sir").as_json

Parameters:

  • options (Hash) (defaults to: nil)

    Options to pass through to the serializer.

Returns:

  • (String)

    The JSON string.



45
46
47
# File 'lib/mongoid/criteria.rb', line 45

def as_json(options = nil)
  entries.as_json(options)
end

#build(attrs = {}) ⇒ Document Also known as: new

Build a document given the selector and return it. Complex criteria, such as $in and $or operations will get ignored.

Examples:

build the document.

Person.where(:title => "Sir").build

Build with selectors getting ignored.

Person.where(:age.gt => 5).build

Returns:

  • (Document)

    A non-persisted document.

Since:

  • 2.0.0



61
62
63
# File 'lib/mongoid/criteria.rb', line 61

def build(attrs = {})
  create_document(:new, attrs)
end

#cacheCriteria

Tells the criteria that the cursor that gets returned needs to be cached. This is so multiple iterations don’t hit the database multiple times, however this is not advisable when working with large data sets as the entire results will get stored in memory.

Examples:

Flag the criteria as cached.

criteria.cache

Returns:



75
76
77
78
79
# File 'lib/mongoid/criteria.rb', line 75

def cache
  crit = clone
  crit.options.merge!(cache: true)
  crit
end

#cached?true, false

Will return true if the cache option has been set.

Examples:

Is the criteria cached?

criteria.cached?

Returns:

  • (true, false)

    If the criteria is flagged as cached.



87
88
89
# File 'lib/mongoid/criteria.rb', line 87

def cached?
  options[:cache] == true
end

#create(attrs = {}) ⇒ Document

Create a document in the database given the selector and return it. Complex criteria, such as $in and $or operations will get ignored.

Examples:

Create the document.

Person.where(:title => "Sir").create

Create with selectors getting ignored.

Person.where(:age.gt => 5).create

Returns:

  • (Document)

    A newly created document.

Since:

  • 2.0.0.rc.1



103
104
105
# File 'lib/mongoid/criteria.rb', line 103

def create(attrs = {})
  create_document(:create, attrs)
end

#create!(attrs = {}) ⇒ Document

Create a document in the database given the selector and return it. Complex criteria, such as $in and $or operations will get ignored. If validation fails, an error will be raised.

Examples:

Create the document.

Person.where(:title => "Sir").create

Create with selectors getting ignored.

Person.where(:age.gt => 5).create

Returns:

  • (Document)

    A newly created document.

Raises:

Since:

  • 3.0.0



122
123
124
# File 'lib/mongoid/criteria.rb', line 122

def create!(attrs = {})
  create_document(:create!, attrs)
end

#documentsArray<Document>

Get the documents from the embedded criteria.

Examples:

Get the documents.

criteria.documents

Returns:

Since:

  • 3.0.0



134
135
136
# File 'lib/mongoid/criteria.rb', line 134

def documents
  @documents ||= []
end

#documents=(docs) ⇒ Array<Document>

Set the embedded documents on the criteria.

Examples:

Set the documents.

Parameters:

  • docs (Array<Document>)

    The embedded documents.

Returns:

  • (Array<Document>)

    The embedded documents.

Since:

  • 3.0.0



147
148
149
# File 'lib/mongoid/criteria.rb', line 147

def documents=(docs)
  @documents = docs
end

#embedded?true, false

Is the criteria for embedded documents?

Examples:

Is the criteria for embedded documents?

criteria.embedded?

Returns:

  • (true, false)

    If the criteria is embedded.

Since:

  • 3.0.0



159
160
161
# File 'lib/mongoid/criteria.rb', line 159

def embedded?
  !!@embedded
end

#execute_or_raise(ids, multi) ⇒ Document+

Execute the criteria or raise an error if no documents found.

Examples:

Execute or raise

criteria.execute_or_raise(id)

Parameters:

  • args (Object)

    The arguments passed.

Returns:

Raises:

Since:

  • 2.0.0



175
176
177
178
179
# File 'lib/mongoid/criteria.rb', line 175

def execute_or_raise(ids, multi)
  result = multiple_from_map_or_db(ids)
  check_for_missing_documents!(result, ids)
  multi ? result : result.first
end

#exists?true, false

Return true if the criteria has some Document or not.

Examples:

Are there any documents for the criteria?

criteria.exists?

Returns:

  • (true, false)

    If documents match.

Since:

  • 1.0.0



189
190
191
# File 'lib/mongoid/criteria.rb', line 189

def exists?
  context.count > 0
end

#extract_idObject

Extract a single id from the provided criteria. Could be in an $and query or a straight _id query.

Examples:

Extract the id.

criteria.extract_id

Returns:

  • (Object)

    The id.

Since:

  • 2.3.0



202
203
204
# File 'lib/mongoid/criteria.rb', line 202

def extract_id
  selector.extract_id
end

#extras(extras) ⇒ Criteria

Adds a criterion to the Criteria that specifies additional options to be passed to the Ruby driver, in the exact format for the driver.

criteria.extras(:limit => 20, :skip => 40)

Examples:

Add extra params to the criteria.

Parameters:

  • extras (Hash)

    The extra driver options.

Returns:

Since:

  • 2.0.0



217
218
219
220
221
# File 'lib/mongoid/criteria.rb', line 217

def extras(extras)
  crit = clone
  crit.options.merge!(extras)
  crit
end

#field_listArray<String>

Get the list of included fields.

Examples:

Get the field list.

criteria.field_list

Returns:

  • (Array<String>)

    The fields.

Since:

  • 2.0.0



231
232
233
234
235
236
237
# File 'lib/mongoid/criteria.rb', line 231

def field_list
  if options[:fields]
    options[:fields].keys.reject{ |key| key == "_type" }
  else
    []
  end
end

#find(*args) ⇒ Array<Document>, Document

Find the matchind document(s) in the criteria for the provided ids.

Examples:

Find by an id.

criteria.find(Moped::BSON::ObjectId.new)

Find by multiple ids.

criteria.find([ Moped::BSON::ObjectId.new, Moped::BSON::ObjectId.new ])

Parameters:

Returns:

Since:

  • 1.0.0



252
253
254
255
256
# File 'lib/mongoid/criteria.rb', line 252

def find(*args)
  ids = args.__find_args__
  raise_invalid if ids.any?(&:nil?)
  for_ids(ids).execute_or_raise(ids, args.multi_arged?)
end

#for_ids(ids) ⇒ Criteria

Adds a criterion to the Criteria that specifies an id that must be matched.

Examples:

Add a single id criteria.

criteria.for_ids([ 1 ])

Add multiple id criteria.

criteria.for_ids([ 1, 2 ])

Parameters:

  • ids (Array)

    The array of ids.

Returns:



269
270
271
272
273
274
275
276
277
# File 'lib/mongoid/criteria.rb', line 269

def for_ids(ids)
  ids = mongoize_ids(ids)
  method = extract_id ? :all_of : :where
  if ids.size > 1
    send(method, { _id: { "$in" => ids }})
  else
    send(method, { _id: ids.first })
  end
end

#freezeCriteria

When freezing a criteria we need to initialize the context first otherwise the setting of the context on attempted iteration will raise a runtime error.

Examples:

Freeze the criteria.

criteria.freeze

Returns:

Since:

  • 2.0.0



289
290
291
# File 'lib/mongoid/criteria.rb', line 289

def freeze
  context and inclusions and super
end

#from_map_or_dbDocument

Get the document from the identity map, and if not found hit the database.

Examples:

Get the document from the map or criteria.

criteria.from_map_or_db

Returns:

Since:

  • 2.2.1



302
303
304
305
306
307
# File 'lib/mongoid/criteria.rb', line 302

def from_map_or_db
  id = extract_id
  id = klass.fields["_id"].mongoize(id) if id
  doc = IdentityMap.get(klass, id || selector.except("_type"))
  doc && doc.matches?(selector) ? doc : first
end

#includes(*relations) ⇒ Criteria

Note:

This will only work if Mongoid’s identity map is enabled. To do so set identity_map_enabled: true in your mongoid.yml

Note:

This will work for embedded relations that reference another collection via belongs_to as well.

Note:

Eager loading brings all the documents into memory, so there is a sweet spot on the performance gains. Internal benchmarks show that eager loading becomes slower around 100k documents, but this will naturally depend on the specific application.

Eager loads all the provided relations. Will load all the documents into the identity map who’s ids match based on the extra query for the ids.

Examples:

Eager load the provided relations.

Person.includes(:posts, :game)

Parameters:

  • relations (Array<Symbol>)

    The names of the relations to eager load.

Returns:

Since:

  • 2.2.0



362
363
364
365
366
367
368
# File 'lib/mongoid/criteria.rb', line 362

def includes(*relations)
  relations.each do |name|
     = klass.reflect_on_association(name)
    inclusions.push() unless inclusions.include?()
  end
  clone
end

#inclusionsArray<Metadata>

Get a list of criteria that are to be executed for eager loading.

Examples:

Get the eager loading inclusions.

Person.includes(:game).inclusions

Returns:

  • (Array<Metadata>)

    The inclusions.

Since:

  • 2.2.0



378
379
380
# File 'lib/mongoid/criteria.rb', line 378

def inclusions
  @inclusions ||= []
end

#inclusions=(value) ⇒ Array<Metadata>

Set the inclusions for the criteria.

Examples:

Set the inclusions.

criteria.inclusions = [ meta ]

Parameters:

  • The (Array<Metadata>)

    inclusions.

Returns:

  • (Array<Metadata>)

    The new inclusions.

Since:

  • 3.0.0



392
393
394
# File 'lib/mongoid/criteria.rb', line 392

def inclusions=(value)
  @inclusions = value
end

#merge(other) ⇒ Criteria

Merges another object with this Criteria and returns a new 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.

Examples:

Merge the criteria with another criteria.

criteri.merge(other_criteria)

Parameters:

  • other (Criteria)

    The other criterion to merge with.

Returns:



407
408
409
410
411
# File 'lib/mongoid/criteria.rb', line 407

def merge(other)
  crit = clone
  crit.merge!(other)
  crit
end

#merge!(other) ⇒ Criteria

Merge the other criteria into this one.

Examples:

Merge another criteria into this criteria.

criteria.merge(Person.where(name: "bob"))

Parameters:

  • other (Criteria)

    The criteria to merge in.

Returns:

Since:

  • 3.0.0



423
424
425
426
427
428
429
430
431
# File 'lib/mongoid/criteria.rb', line 423

def merge!(other)
  criteria = other.to_criteria
  selector.merge!(criteria.selector)
  options.merge!(criteria.options)
  self.documents = criteria.documents.dup unless criteria.documents.empty?
  self.scoping_options = criteria.scoping_options
  self.inclusions = (inclusions + criteria.inclusions.dup).uniq
  self
end

#multiple_from_map_or_db(ids) ⇒ Array<Document>

Get the documents from the identity map, and if not found hit the database.

Examples:

Get the documents from the map or criteria.

criteria.multiple_from_map_or_db(ids)

Parameters:

  • The (ids)

    searched ids.

Returns:

  • (Array<Document>)

    The found documents.



318
319
320
321
322
323
# File 'lib/mongoid/criteria.rb', line 318

def multiple_from_map_or_db(ids)
  return entries if embedded?
  ids = mongoize_ids(ids)
  result = from_identity_map(ids)
  ids.empty? ? result : result + from_database(ids)
end

#only(*args) ⇒ Criteria

Overriden to include _type in the fields.

Examples:

Limit the fields returned from the database.

Band.only(:name)

Parameters:

  • args (Array<Symbol>)

    The names of the fields.

Returns:

Since:

  • 1.0.0



443
444
445
446
447
448
449
450
451
# File 'lib/mongoid/criteria.rb', line 443

def only(*args)
  return clone if args.empty?
  args = args.flatten
  if klass.hereditary?
    super(*args.push(:_type))
  else
    super(*args)
  end
end

#respond_to?(name, include_private = false) ⇒ true, false

Returns true if criteria responds to the given method.

Examples:

Does the criteria respond to the method?

crtiteria.respond_to?(:each)

Parameters:

  • name (Symbol)

    The name of the class method on the Document.

  • include_private (true, false) (defaults to: false)

    Whether to include privates.

Returns:

  • (true, false)

    If the criteria responds to the method.



462
463
464
# File 'lib/mongoid/criteria.rb', line 462

def respond_to?(name, include_private = false)
  super || klass.respond_to?(name) || entries.respond_to?(name, include_private)
end

#to_criteriaCriteria

Convenience for objects that want to be merged into a criteria.

Examples:

Convert to a criteria.

criteria.to_criteria

Returns:

Since:

  • 3.0.0



476
477
478
# File 'lib/mongoid/criteria.rb', line 476

def to_criteria
  self
end

#to_procProc

Convert the criteria to a proc.

Examples:

Convert the criteria to a proc.

criteria.to_proc

Returns:

  • (Proc)

    The wrapped criteria.

Since:

  • 3.0.0



488
489
490
# File 'lib/mongoid/criteria.rb', line 488

def to_proc
  ->{ self }
end

#type(types) ⇒ Criteria

Adds a criterion to the Criteria that specifies a type or an Array of types that must be matched.

Examples:

Match only specific models.

criteria.type('Browser')
criteria.type(['Firefox', 'Browser'])

Parameters:

  • types (Array<String>)

    The types to match against.

Returns:



502
503
504
# File 'lib/mongoid/criteria.rb', line 502

def type(types)
  any_in(_type: Array(types))
end

#where(expression) ⇒ Criteria

This is the general entry point for most MongoDB queries. This either creates a standard field: value selection, and expanded selection with the use of hash methods, or a $where selection if a string is provided.

Examples:

Add a standard selection.

criteria.where(name: "syd")

Add a javascript selection.

criteria.where("this.name == 'syd'")

Parameters:

  • criterion (String, Hash)

    The javascript or standard selection.

Returns:

Raises:

  • (UnsupportedJavascript)

    If provided a string and the criteria is embedded.

Since:

  • 1.0.0



524
525
526
527
528
529
# File 'lib/mongoid/criteria.rb', line 524

def where(expression)
  if expression.is_a?(::String) && embedded?
    raise Errors::UnsupportedJavascript.new(klass, expression)
  end
  super
end