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

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

#includes, #inclusions, #inclusions=

Methods included from Findable

#execute_or_raise, #for_ids, #multiple_from_db

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.



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

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.



530
531
532
533
534
535
536
537
538
539
540
# File 'lib/mongoid/criteria.rb', line 530

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

Instance Attribute Details

#associationObject

Returns the value of attribute association.



68
69
70
# File 'lib/mongoid/criteria.rb', line 68

def association
  @association
end

#embeddedObject

Returns the value of attribute embedded.



68
69
70
# File 'lib/mongoid/criteria.rb', line 68

def embedded
  @embedded
end

#klassObject

Returns the value of attribute klass.



68
69
70
# File 'lib/mongoid/criteria.rb', line 68

def klass
  @klass
end

#parent_documentObject

Returns the value of attribute parent_document.



68
69
70
# File 'lib/mongoid/criteria.rb', line 68

def parent_document
  @parent_document
end

Class Method Details

.from_hash(hash) ⇒ Criteria

Convert the given hash to a criteria. Will iterate over each keys in the hash which must correspond to method on a criteria object. The hash must also include a “klass” key.

Examples:

Convert the hash to a criteria.

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

Parameters:

  • hash (Hash)

    The hash to convert.

Returns:



55
56
57
58
59
60
61
# File 'lib/mongoid/criteria.rb', line 55

def from_hash(hash)
  criteria = Criteria.new(hash.delete(:klass) || hash.delete('klass'))
  hash.each_pair do |method, args|
    criteria = criteria.__send__(method, 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.



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

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.



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

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.



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

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.



140
141
142
# File 'lib/mongoid/criteria.rb', line 140

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

#documentsArray<Document>

Get the documents from the embedded criteria.

Examples:

Get the documents.

criteria.documents

Returns:



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

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.



161
162
163
# File 'lib/mongoid/criteria.rb', line 161

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.



171
172
173
# File 'lib/mongoid/criteria.rb', line 171

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.



301
302
303
# File 'lib/mongoid/criteria.rb', line 301

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.



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

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:



195
196
197
198
199
# File 'lib/mongoid/criteria.rb', line 195

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.



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

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

critera.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:



124
125
126
127
128
129
130
# File 'lib/mongoid/criteria.rb', line 124

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:



466
467
468
469
470
471
472
473
474
# File 'lib/mongoid/criteria.rb', line 466

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:



223
224
225
# File 'lib/mongoid/criteria.rb', line 223

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

    The other criterion to merge with.

Returns:



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

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:



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

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
end

#noneCriteria

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

Examples:

Return a none criteria.

criteria.none

Returns:



291
292
293
# File 'lib/mongoid/criteria.rb', line 291

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 ([ Symbol | Array<Symbol> ]...)

    The field name(s).

Returns:



313
314
315
316
317
318
319
320
321
322
323
# File 'lib/mongoid/criteria.rb', line 313

def only(*args)
  args = args.flatten
  return clone if args.empty?
  if (args & Fields::IDS).empty?
    args.unshift(:_id)
  end
  if klass.hereditary?
    args.push(klass.discriminator_key.to_sym)
  end
  super(*args)
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:



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

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?

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.



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

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:



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

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.



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

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:



399
400
401
# File 'lib/mongoid/criteria.rb', line 399

def type(types)
  any_in(self.discriminator_key.to_sym => Array(types))
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.



420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
# File 'lib/mongoid/criteria.rb', line 420

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 implemetation that super invokes supports
  # any number of arguments, but we don't presently allow mutiple
  # arguments through this method. This API can be reconsidered in the
  # future.
  if args.length > 1
    raise ArgumentError, "Criteria#where requires zero or one arguments (given #{args.length})"
  end
  if args.length == 1
    expression = args.first
    if expression.is_a?(::String) && embedded?
      raise Errors::UnsupportedJavascript.new(klass, expression)
    end
  end
  super
end

#without(*args) ⇒ Criteria

Overriden to exclude _id from the fields.

Examples:

Exclude fields returned from the database.

Band.without(:name)

Parameters:

  • *args (Symbol...)

    The field name(s).

Returns:



347
348
349
350
# File 'lib/mongoid/criteria.rb', line 347

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

#without_optionsCriteria

Get a version of this criteria without the options.

Examples:

Get the criteria without options.

criteria.without_options

Returns:



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

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