Class: Mongoid::Criteria

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Inspectable, Mongoid::Clients::Options, Mongoid::Clients::Sessions, Contextual, Findable, Includable, Marshalable, Modifiable, Options, Queryable, Scopable
Defined in:
lib/mongoid/criteria.rb,
lib/mongoid/criteria/options.rb,
lib/mongoid/criteria/findable.rb,
lib/mongoid/criteria/scopable.rb,
lib/mongoid/criteria/queryable.rb,
lib/mongoid/criteria/includable.rb,
lib/mongoid/criteria/modifiable.rb,
lib/mongoid/criteria/permission.rb,
lib/mongoid/criteria/translator.rb,
lib/mongoid/criteria/marshalable.rb,
lib/mongoid/criteria/queryable/key.rb,
lib/mongoid/criteria/queryable/smash.rb,
lib/mongoid/criteria/queryable/options.rb,
lib/mongoid/criteria/queryable/optional.rb,
lib/mongoid/criteria/queryable/pipeline.rb,
lib/mongoid/criteria/queryable/selector.rb,
lib/mongoid/criteria/queryable/storable.rb,
lib/mongoid/criteria/queryable/macroable.rb,
lib/mongoid/criteria/queryable/mergeable.rb,
lib/mongoid/criteria/queryable/aggregable.rb,
lib/mongoid/criteria/queryable/expandable.rb,
lib/mongoid/criteria/queryable/selectable.rb,
lib/mongoid/criteria/queryable/extensions/set.rb,
lib/mongoid/criteria/queryable/extensions/date.rb,
lib/mongoid/criteria/queryable/extensions/hash.rb,
lib/mongoid/criteria/queryable/extensions/time.rb,
lib/mongoid/criteria/queryable/extensions/array.rb,
lib/mongoid/criteria/queryable/extensions/range.rb,
lib/mongoid/criteria/queryable/extensions/object.rb,
lib/mongoid/criteria/queryable/extensions/regexp.rb,
lib/mongoid/criteria/queryable/extensions/string.rb,
lib/mongoid/criteria/queryable/extensions/symbol.rb,
lib/mongoid/criteria/queryable/extensions/boolean.rb,
lib/mongoid/criteria/queryable/extensions/numeric.rb,
lib/mongoid/criteria/queryable/extensions/date_time.rb,
lib/mongoid/criteria/queryable/extensions/nil_class.rb,
lib/mongoid/criteria/queryable/extensions/big_decimal.rb,
lib/mongoid/criteria/queryable/extensions/time_with_zone.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, Includable, Marshalable, Modifiable, Options, Permission, Queryable, Scopable, Translator

Constant Summary collapse

ALLOWED_FROM_HASH_METHODS =

Allowed methods for from_hash to prevent arbitrary method execution. Only query-building methods are allowed, not execution or modification methods.

%i[
  all all_in all_of and any_in any_of asc ascending
  batch_size between
  collation comment cursor_type
  desc descending
  elem_match eq exists extras
  geo_spatial group gt gte
  hint
  in includes
  limit lt lte
  max_distance max_scan max_time_ms merge mod
  ne near near_sphere nin no_timeout none none_of nor not not_in
  offset only or order order_by
  project
  raw read reorder
  scoped skip slice snapshot
  text_search type
  unscoped unwind
  where with_size with_type without
].freeze
CHECK =

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

[]

Instance Attribute Summary collapse

Attributes included from Modifiable

#create_attrs, #create_attrs Additional attributes to add to the Document upon creation.

Attributes included from Queryable

#aliases, #aliases The aliases., #serializers, #serializers The serializers.

Attributes included from Queryable::Optional

#options, #options The query options.

Attributes included from Queryable::Aggregable

#aggregating, #aggregating Flag for whether or not we are aggregating., #pipeline, #pipeline The aggregation pipeline.

Attributes included from Queryable::Mergeable

#strategy, #strategy The name of the current strategy.

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Mongoid::Clients::Sessions

included

Methods included from Mongoid::Clients::Options

#collection, #collection_name, #mongo_client, #persistence_context, #persistence_context?, #with

Methods included from Scopable

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

Methods included from Modifiable

#build, #create, #create!, #create_with, #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 Includable

#eager_load, #includes, #inclusions, #inclusions=, #use_lookup?

Methods included from Findable

#execute_or_raise, #for_ids, #multiple_from_db

Methods included from Queryable

#to_mql

Methods included from Queryable::Optional

#ascending, #batch_size, #collation, #comment, #cursor_type, #descending, forwardables, #hint, #limit, #max_scan, #max_time_ms, #no_timeout, #order_by, #reorder, #skip, #slice, #snapshot

Methods included from Queryable::Macroable

#key

Methods included from Selectable

#atomic_selector

Methods included from Queryable::Aggregable

#aggregating?, #group, #project, #unwind

Methods included from Queryable::Mergeable

#and_with_operator, #intersect, #override, #reset_strategies!, #union

Methods included from Queryable::Storable

#add_field_expression, #add_logical_operator_expression, #add_one_expression, #add_operator_expression

Methods included from Contextual

#context, #load_async

Constructor Details

#initialize(klass) ⇒ Criteria

Initialize the new criteria.

Examples:

Init the new criteria.

Criteria.new(Band)

Parameters:

  • klass (Class)

    The model class.



323
324
325
326
327
328
# File 'lib/mongoid/criteria.rb', line 323

def initialize(klass)
  @klass = klass
  @embedded = nil
  @none = nil
  klass ? super(klass.aliased_fields, klass.fields, klass.relations, klass.aliased_associations) : super({}, {}, {}, {})
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missingObject (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 (Object...)

    The arguments.

Returns:

  • (Object)

    The result of the method call.



619
620
621
622
623
624
625
626
627
628
629
# File 'lib/mongoid/criteria.rb', line 619

ruby2_keywords 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)
    entries.send(name, *args, &block)
  else
    super
  end
end

Instance Attribute Details

#_raw_resultsnil | Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

An internal helper for getting/setting the "raw" flag on a given criteria object.

Returns:

  • (nil | Hash)

    If set, it is a hash with two keys, :raw and :typed, that describe whether raw results should be returned, and whether they ought to be typecast.



244
245
246
# File 'lib/mongoid/criteria.rb', line 244

def _raw_results
  @_raw_results
end

#associationObject

Returns the value of attribute association.



100
101
102
# File 'lib/mongoid/criteria.rb', line 100

def association
  @association
end

#documentsArray<Document>

Get the documents from the embedded criteria.

Examples:

Get the documents.

criteria.documents

Returns:



183
184
185
# File 'lib/mongoid/criteria.rb', line 183

def documents
  @documents ||= []
end

#embeddedObject

Returns the value of attribute embedded.



100
101
102
# File 'lib/mongoid/criteria.rb', line 100

def embedded
  @embedded
end

#klassObject

Returns the value of attribute klass.



100
101
102
# File 'lib/mongoid/criteria.rb', line 100

def klass
  @klass
end

#parent_documentObject

Returns the value of attribute parent_document.



100
101
102
# File 'lib/mongoid/criteria.rb', line 100

def parent_document
  @parent_document
end

Class Method Details

.from_hash(hash) ⇒ Criteria

Deprecated.

This method is deprecated and will be removed in a future release.

Convert the given hash to a criteria. Will iterate over each keys in the hash which must correspond to an allowed method on a criteria object. The hash can include a "klass" key that specifies the model class for the criteria.

Examples:

Convert the hash to a criteria.

Criteria.from_hash({ klass: Band, where: { name: "Depeche Mode" })

Parameters:

  • hash (Hash)

    The hash to convert.

Returns:

Raises:

  • (ArgumentError)

    If a method is not allowed in from_hash.



81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/mongoid/criteria.rb', line 81

def from_hash(hash)
  criteria = Criteria.new(hash.delete(:klass) || hash.delete('klass'))
  hash.each_pair do |method, args|
    method_sym = method.to_sym
    unless ALLOWED_FROM_HASH_METHODS.include?(method_sym)
      raise ArgumentError, "Method '#{method}' is not allowed in from_hash"
    end

    criteria = criteria.public_send(method_sym, args)
  end
  criteria
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.



110
111
112
113
114
# File 'lib/mongoid/criteria.rb', line 110

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

  entries == other
end

#_enumerable_findObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



24
# File 'lib/mongoid/criteria.rb', line 24

alias _enumerable_find find

#_findable_findObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



31
# File 'lib/mongoid/criteria.rb', line 31

alias _findable_find find

#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.



173
174
175
# File 'lib/mongoid/criteria.rb', line 173

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



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

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.



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

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.



272
273
274
# File 'lib/mongoid/criteria.rb', line 272

def extract_id
  selector['_id'] || selector[:_id] || selector['id'] || selector[: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:



285
286
287
288
289
# File 'lib/mongoid/criteria.rb', line 285

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.



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

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

#find(*args) {|Object| ... } ⇒ Document | Array<Document> | nil

Note:

Each argument can be an individual id, an array of ids or a nested array. Each array will be flattened.

Finds one or many documents given the provided _id values, or filters the documents in the current scope in the application process space after loading them if needed.

If this method is not given a block, it delegates to Findable#find and finds one or many documents for the provided _id values.

If this method is given a block, it delegates to Enumerable#find and returns the first document of those found by the current Criteria object for which the block returns a truthy value.

Note that the "default proc" argument of Enumerable is not specially treated by Mongoid - the decision between delegating to Findable vs Enumerable is made solely based on whether find is passed a block.

Examples:

Finds a document by its _id, invokes Findable#find.

criteria.find("1234")

Finds the first matching document using a block, invokes Enumerable#find.

criteria.find { |item| item.name == "Depeche Mode" }

Finds the first matching document using a block using the default Proc, invokes Enumerable#find.

criteria.find(-> { "Default Band" }) { |item| item.name == "Milwaukee Mode" }

Tries to find a document whose _id is the stringification of the provided Proc, typically failing.

enumerator = criteria.find(-> { "Default Band" })

Parameters:

  • *args ([ Object | Array<Object> ]...)

    The id(s).

  • &block

    Optional block to pass.

Yields:

  • (Object)

    Yields each enumerable element to the block.

Returns:

Raises:

  • Errors::DocumentNotFound If the parameters were _id values and not all documents are found and the raise_not_found_error Mongoid configuration option is truthy.

See Also:



157
158
159
160
161
162
163
# File 'lib/mongoid/criteria.rb', line 157

def find(*args, &block)
  if block_given?
    _enumerable_find(*args, &block)
  else
    _findable_find(*args)
  end
end

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

Deprecated.

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:



553
554
555
556
557
558
559
560
561
# File 'lib/mongoid/criteria.rb', line 553

def for_js(javascript, scope = {})
  code = if scope.empty?
           # CodeWithScope is not supported for $where as of MongoDB 4.4
           BSON::Code.new(javascript)
         else
           BSON::CodeWithScope.new(javascript, scope)
         end
  js_query(code)
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:



313
314
315
# File 'lib/mongoid/criteria.rb', line 313

def freeze
  context and inclusions and super
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.

criteria.merge(other_criteria)

Merge the criteria with a hash. The hash must contain a klass

key that specifies the model class for the criteria and the key/value
pairs correspond to method names/args.

criteria.merge({
  klass: Band,
  where: { name: "Depeche Mode" },
  order_by: { name: 1 }
})

Parameters:

  • other (Criteria | Hash)

    The other criterion to merge with.

Returns:



351
352
353
354
355
# File 'lib/mongoid/criteria.rb', line 351

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 | Hash)

    The criteria to merge in.

Returns:



365
366
367
368
369
370
371
372
373
374
375
# File 'lib/mongoid/criteria.rb', line 365

def merge!(other)
  other = self.class.from_hash(other) if other.is_a?(Hash)
  selector.merge!(other.selector)
  options.merge!(other.options)
  self.documents = other.documents.dup unless other.documents.empty?
  self.scoping_options = other.scoping_options
  self.inclusions = (inclusions + other.inclusions).uniq
  self._raw_results = _raw_results || other._raw_results
  @use_lookup ||= other.use_lookup?
  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:



384
385
386
# File 'lib/mongoid/criteria.rb', line 384

def none
  @none = true and self
end

#only(*args) ⇒ Criteria

Overridden to include _type in the fields.

Examples:

Limit the fields returned from the database.

Band.only(:name)

Parameters:

  • *args ([ Symbol | Array<Symbol> ]...)

    The field name(s).

Returns:



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

def only(*args)
  args = args.flatten
  return clone if args.empty?

  args.unshift(:_id) if (args & Fields::IDS).empty?
  args.push(klass.discriminator_key.to_sym) if klass.hereditary?
  super
end

#raise_eager_error(is_eager_load, klass, relation) ⇒ Object



115
116
117
118
119
120
121
# File 'lib/mongoid/criteria/includable.rb', line 115

def raise_eager_error(is_eager_load, klass, relation)
  if is_eager_load
    raise ArgumentError, "Eager loading only supports arguments that are the names of associations on #{klass}"
  end

  raise Errors::InvalidIncludes.new(klass, [ relation ])
end

#raw(raw_results = true, typed: nil) ⇒ Criteria

Produce a clone of the current criteria object with it's "raw" setting set to the given value. A criteria set to "raw" will return all results as raw hashes. If typed is true, the values in the hashes will be typecast according to the fields that they correspond to.

When "raw" is not set (or if raw_results is false), the criteria will return all results as instantiated Document instances.

Examples:

Return query results as raw hashes:

Person.where(city: 'Boston').raw

Parameters:

  • raw_results (true | false) (defaults to: true)

    Whether the new criteria should be placed in "raw" mode or not.

  • typed (true | false) (defaults to: nil)

    Whether the raw results should be typecast before being returned. Default is true if raw_results is false, and false otherwise.

Returns:

  • (Criteria)

    the cloned criteria object.

Raises:

  • (ArgumentError)


224
225
226
227
228
229
230
231
232
233
234
# File 'lib/mongoid/criteria.rb', line 224

def raw(raw_results = true, typed: nil)
  # default for typed is true when raw_results is false, and false when
  # raw_results is true.
  typed = !raw_results if typed.nil?

  raise ArgumentError, 'instantiated results must be typecast' if !typed && !raw_results

  clone.tap do |criteria|
    criteria._raw_results = { raw: raw_results, typed: typed }
  end
end

#raw_results?true | false

Predicate that answers the question: is this criteria object currently in raw mode? (See #raw for a description of raw mode.)

Returns:

  • (true | false)

    whether the criteria is in raw mode or not.



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

def raw_results?
  _raw_results && _raw_results[:raw]
end

#read(value = nil) ⇒ Criteria

Set the read preference for the criteria.

Examples:

Set the read preference.

criteria.read(mode: :primary_preferred)

Parameters:

  • value (Hash) (defaults to: nil)

    The mode preference.

Returns:



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

def read(value = nil)
  clone.tap do |criteria|
    criteria.options.merge!(read: value)
  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?

criteria.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.



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

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

#to_criteriaCriteria

Deprecated.

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

Examples:

Convert to a criteria.

criteria.to_criteria

Returns:



464
465
466
# File 'lib/mongoid/criteria.rb', line 464

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.



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

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:



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

def type(types)
  any_in(discriminator_key.to_sym => Array(types))
end

#typecast_results?true | false

Predicate that answers the question: should the results returned by this criteria object be typecast? (See #raw for a description of this.) The answer is meaningless unless #raw_results? is true, since if instantiated document objects are returned they will always be typecast.

Returns:

  • (true | false)

    whether the criteria should return typecast results.



261
262
263
# File 'lib/mongoid/criteria.rb', line 261

def typecast_results?
  _raw_results && _raw_results[:typed]
end

#where(*args) ⇒ 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:

  • *args ([ Hash | String ]...)

    The standard selection or javascript string.

Returns:

Raises:

  • (UnsupportedJavascript)

    If provided a string and the criteria is embedded.



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

def where(*args)
  # Historically this method required exactly one argument.
  # As of https://jira.mongodb.org/browse/MONGOID-4804 it also accepts
  # zero arguments.
  # The underlying where implementation that super invokes supports
  # any number of arguments, but we don't presently allow multiple
  # arguments through this method. This API can be reconsidered in the
  # future.
  raise ArgumentError, "Criteria#where requires zero or one arguments (given #{args.length})" if args.length > 1

  if args.length == 1
    expression = args.first
    raise Errors::UnsupportedJavascript.new(klass, expression) if expression.is_a?(::String) && embedded?
  end
  super
end

#without(*args) ⇒ Criteria

Overridden to exclude _id from the fields.

Examples:

Exclude fields returned from the database.

Band.without(:name)

Parameters:

  • *args (Symbol...)

    The field name(s).

Returns:



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

def without(*args)
  args -= id_fields
  super
end

#without_optionsCriteria

Get a version of this criteria without the options.

Examples:

Get the criteria without options.

criteria.without_options

Returns:



533
534
535
536
537
# File 'lib/mongoid/criteria.rb', line 533

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