Class: Mongoid::Criteria

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Contextual, Findable, Inspectable, Marshalable, Modifiable, Scopable, Sessions::Options, Origin::Queryable
Defined in:
lib/mongoid/criteria.rb,
lib/mongoid/criteria/findable.rb,
lib/mongoid/criteria/scopable.rb,
lib/mongoid/criteria/modifiable.rb,
lib/mongoid/criteria/permission.rb,
lib/mongoid/criteria/inspectable.rb,
lib/mongoid/criteria/marshalable.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.

Defined Under Namespace

Modules: Findable, Inspectable, Marshalable, Modifiable, Permission, Scopable

Constant Summary collapse

CHECK =

Static array used to check with method missing - we only need to ever instantiate once.

Since:

  • 4.0.0

[]

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Sessions::Options

#collection_name, #mongo_session, #persistence_options, #with

Methods included from Scopable

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

Methods included from Modifiable

#build, #create, #create!, #find_or_create_by, #find_or_create_by!, #find_or_initialize_by, #first_or_create, #first_or_create!, #first_or_initialize

Methods included from Marshalable

#marshal_dump, #marshal_load

Methods included from Inspectable

#inspect

Methods included from Findable

#execute_or_raise, #find, #for_ids, #multiple_from_db

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



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

def initialize(klass)
  @klass = klass
  klass ? super(klass.aliased_fields, klass.fields) : super({}, {})
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



515
516
517
518
519
520
521
522
523
524
525
# File 'lib/mongoid/criteria.rb', line 515

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

Instance Attribute Details

#embeddedObject

Returns the value of attribute embedded.



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

def embedded
  @embedded
end

#klassObject

Returns the value of attribute klass.



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

def klass
  @klass
end

#metadataObject

Returns the value of attribute metadata.



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

def 
  @metadata
end

#parent_documentObject

Returns the value of attribute parent_document.



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

def parent_document
  @parent_document
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



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

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.



59
60
61
# File 'lib/mongoid/criteria.rb', line 59

def as_json(options = nil)
  entries.as_json(options)
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:



72
73
74
75
76
# File 'lib/mongoid/criteria.rb', line 72

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.



84
85
86
# File 'lib/mongoid/criteria.rb', line 84

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

#documentsArray<Document>

Get the documents from the embedded criteria.

Examples:

Get the documents.

criteria.documents

Returns:

Since:

  • 3.0.0



96
97
98
# File 'lib/mongoid/criteria.rb', line 96

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



109
110
111
# File 'lib/mongoid/criteria.rb', line 109

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



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

def embedded?
  !!@embedded
end

#empty_and_chainable?true, false

Is the criteria an empty but chainable criteria?

Examples:

Is the criteria a none criteria?

criteria.empty_and_chainable?

Returns:

  • (true, false)

    If the criteria is a none.

Since:

  • 4.0.0



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

def empty_and_chainable?
  !!@none
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



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

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



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

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



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

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

#for_js(javascript, scope = {}) ⇒ Criteria

Find documents by the provided javascript and scope. Uses a $where but is different from Criteria#where in that it will pass a code object to the query instead of a pure string. Safe against Javascript injection attacks.

Examples:

Find by javascript.

Band.for_js("this.name = param", param: "Tool")

Parameters:

  • javascript (String)

    The javascript to execute in the $where.

  • scope (Hash) (defaults to: {})

    The scope for the code.

Returns:

Since:

  • 3.1.0



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

def for_js(javascript, scope = {})
  js_query(BSON::CodeWithScope.new(javascript, scope))
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



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

def freeze
  context and inclusions and super
end

#includes(*relations) ⇒ Criteria

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



219
220
221
222
223
224
225
226
# File 'lib/mongoid/criteria.rb', line 219

def includes(*relations)
  relations.flatten.each do |name|
     = klass.reflect_on_association(name)
    raise Errors::InvalidIncludes.new(klass, relations) unless 
    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



236
237
238
# File 'lib/mongoid/criteria.rb', line 236

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



250
251
252
# File 'lib/mongoid/criteria.rb', line 250

def inclusions=(value)
  @inclusions = value
end

#merge(other) ⇒ Criteria

criteria.merge({

  klass: Band,
  where: { name: "Depeche Mode" },
  order_by: { name: 1 }
})

Parameters:

  • other (Criteria)

    The other criterion to merge with.

Returns:



274
275
276
277
278
# File 'lib/mongoid/criteria.rb', line 274

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



290
291
292
293
294
295
296
297
298
# File 'lib/mongoid/criteria.rb', line 290

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

#noneCriteria

Returns a criteria that will always contain zero results and never hits the database.

Examples:

Return a none criteria.

criteria.none

Returns:

Since:

  • 4.0.0



309
310
311
# File 'lib/mongoid/criteria.rb', line 309

def none
  @none = true and self
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



335
336
337
338
339
340
341
342
343
# File 'lib/mongoid/criteria.rb', line 335

def only(*args)
  return clone if args.flatten.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.



354
355
356
# File 'lib/mongoid/criteria.rb', line 354

def respond_to?(name, include_private = false)
  super || klass.respond_to?(name) || CHECK.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



368
369
370
# File 'lib/mongoid/criteria.rb', line 368

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



380
381
382
# File 'lib/mongoid/criteria.rb', line 380

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:



394
395
396
# File 'lib/mongoid/criteria.rb', line 394

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



416
417
418
419
420
421
# File 'lib/mongoid/criteria.rb', line 416

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

#without_optionsCriteria

Get a version of this criteria without the options.

Examples:

Get the criteria without options.

criteria.without_options

Returns:

Since:

  • 3.0.4



432
433
434
435
436
# File 'lib/mongoid/criteria.rb', line 432

def without_options
  crit = clone
  crit.options.clear
  crit
end