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

- (Criteria) initialize(klass)

Initialize the new criteria.

Examples:

Init the new criteria.

Criteria.new(Band)

Parameters:

  • klass (Class)

    The model class.

Since:

  • 1.0.0



329
330
331
332
# File 'lib/mongoid/criteria.rb', line 329

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

- (Object) method_missing(name, *args, &block) (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



586
587
588
589
590
591
592
593
594
# File 'lib/mongoid/criteria.rb', line 586

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

- (Object) embedded

Returns the value of attribute embedded



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

def embedded
  @embedded
end

- (Object) klass

Returns the value of attribute klass



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

def klass
  @klass
end

Instance Method Details

- (true, false) ==(other)

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
36
37
38
# File 'lib/mongoid/criteria.rb', line 32

def ==(other)
  case other
  when Criteria then super
  when Enumerable then entries == other
  else false
  end
end

- (String) as_json(options = nil)

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.



48
49
50
# File 'lib/mongoid/criteria.rb', line 48

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

- (Document) build(attrs = {})

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



64
65
66
# File 'lib/mongoid/criteria.rb', line 64

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

- (Criteria) cache

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:



77
78
79
80
81
# File 'lib/mongoid/criteria.rb', line 77

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

- (true, false) cached?

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.



89
90
91
# File 'lib/mongoid/criteria.rb', line 89

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

- (Document) create(attrs = {})

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



105
106
107
# File 'lib/mongoid/criteria.rb', line 105

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

- (Document) create!(attrs = {})

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



124
125
126
# File 'lib/mongoid/criteria.rb', line 124

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

- (Array<Document>) documents

Get the documents from the embedded criteria.

Examples:

Get the documents.

criteria.documents

Returns:

Since:

  • 3.0.0



136
137
138
# File 'lib/mongoid/criteria.rb', line 136

def documents
  @documents ||= []
end

- (Array<Document>) documents=(docs)

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



149
150
151
# File 'lib/mongoid/criteria.rb', line 149

def documents=(docs)
  @documents = docs
end

- (Document+) execute_or_raise(ids, multi)

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



165
166
167
168
169
170
171
# File 'lib/mongoid/criteria.rb', line 165

def execute_or_raise(ids, multi)
  result = multiple_from_map_or_db(ids)
  if (result.size < ids.size) && Mongoid.raise_not_found_error
    raise Errors::DocumentNotFound.new(klass, ids, ids - result.map(&:_id))
  end
  multi ? result : result.first
end

- (true, false) exists?

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



181
182
183
# File 'lib/mongoid/criteria.rb', line 181

def exists?
  context.count > 0
end

- (Object) extract_id

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



194
195
196
# File 'lib/mongoid/criteria.rb', line 194

def extract_id
  selector.extract_id
end

- (Criteria) extras(extras)

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



209
210
211
212
213
# File 'lib/mongoid/criteria.rb', line 209

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

- (Array<String>) field_list

Get the list of included fields.

Examples:

Get the field list.

criteria.field_list

Returns:

  • (Array<String>)

    The fields.

Since:

  • 2.0.0



223
224
225
226
227
228
229
# File 'lib/mongoid/criteria.rb', line 223

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

- (Array<Document>, Document) find(*args)

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

Examples:

Find by an id.

criteria.find(BSON::ObjectId.new)

Find by multiple ids.

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

Parameters:

  • args (Array<BSON::ObjectId>)

    The ids to search for.

Returns:

Since:

  • 1.0.0



244
245
246
247
248
249
250
251
# File 'lib/mongoid/criteria.rb', line 244

def find(*args)
  multi = args.first.is_a?(::Array) || args.first.is_a?(::Range) || args.size > 1
  ids = *args.flat_map do |arg|
    arg.is_a?(::Range) ? arg.to_a : arg
  end
  raise_invalid if ids.any?(&:nil?)
  for_ids(ids).execute_or_raise(ids, multi)
end

- (Criteria) for_ids(ids)

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:



264
265
266
267
268
269
270
271
272
# File 'lib/mongoid/criteria.rb', line 264

def for_ids(ids)
  field = klass.fields["_id"]
  method = extract_id ? :all_of : :where
  if ids.size > 1
    send(method, { _id: { "$in" => ids.map{ |id| field.mongoize(id) }}})
  else
    send(method, { _id: field.mongoize(ids.first) })
  end
end

- (Criteria) freeze

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



284
285
286
# File 'lib/mongoid/criteria.rb', line 284

def freeze
  context and inclusions and super
end

- (Document) from_map_or_db

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



297
298
299
300
# File 'lib/mongoid/criteria.rb', line 297

def from_map_or_db
  doc = IdentityMap.get(klass, extract_id || selector)
  doc && doc.matches?(selector) ? doc : first
end

- (Criteria) includes(*relations)

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



358
359
360
361
362
363
# File 'lib/mongoid/criteria.rb', line 358

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

- (Array<Metadata>) inclusions

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



373
374
375
# File 'lib/mongoid/criteria.rb', line 373

def inclusions
  @inclusions ||= []
end

- (Array<Metadata>) inclusions=(value)

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



387
388
389
# File 'lib/mongoid/criteria.rb', line 387

def inclusions=(value)
  @inclusions = value
end

- (Criteria) merge(other)

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:



402
403
404
405
406
# File 'lib/mongoid/criteria.rb', line 402

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

- (Criteria) merge!(other)

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



418
419
420
421
422
423
424
425
426
# File 'lib/mongoid/criteria.rb', line 418

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

- (Array<Document>) multiple_from_map_or_db(ids)

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.



311
312
313
314
315
316
317
318
319
# File 'lib/mongoid/criteria.rb', line 311

def multiple_from_map_or_db(ids)
  return entries if klass.embedded?
  result = []
  ids.reject! do |id|
    doc = IdentityMap.get(klass, id)
    doc && doc.matches?(selector) ? result.push(doc) : false
  end
  result + any_in(id: ids).entries
end

- (Criteria) only(*args)

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



438
439
440
441
# File 'lib/mongoid/criteria.rb', line 438

def only(*args)
  return clone if args.empty?
  super(*(args + [:_type]))
end

- (true, false) respond_to?(name, include_private = 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.



452
453
454
# File 'lib/mongoid/criteria.rb', line 452

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

- (Criteria) to_criteria

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

Examples:

Convert to a criteria.

criteria.to_criteria

Returns:

Since:

  • 3.0.0



466
467
468
# File 'lib/mongoid/criteria.rb', line 466

def to_criteria
  self
end

- (Proc) to_proc

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



478
479
480
# File 'lib/mongoid/criteria.rb', line 478

def to_proc
  ->{ self }
end

- (Criteria) type(types)

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:



492
493
494
495
# File 'lib/mongoid/criteria.rb', line 492

def type(types)
  types = [types] unless types.is_a?(Array)
  any_in(_type: types)
end

- (Criteria) where(expression)

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



515
516
517
518
519
520
# File 'lib/mongoid/criteria.rb', line 515

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