Module: Mongoid::Criterion::Inclusion

Included in:
Mongoid::Criteria
Defined in:
lib/mongoid/criterion/inclusion.rb

Instance Method Summary collapse

Instance Method Details

#all(attributes = {}) ⇒ Criteria Also known as: all_in

Adds a criterion to the Criteria that specifies values that must all be matched in order to return results. Similar to an “in” clause but the underlying conditional logic is an “AND” and not an “OR”. The MongoDB conditional operator that will be used is “$all”.

Examples:

Adding the criterion.

criteria.all(:field => ["value1", "value2"])
criteria.all(:field1 => ["value1", "value2"], :field2 => ["value1"])

Parameters:

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

    Name/value pairs that all must match.

Returns:

  • (Criteria)

    A new criteria with the added selector.



18
19
20
# File 'lib/mongoid/criterion/inclusion.rb', line 18

def all(attributes = {})
  update_selector(attributes, "$all")
end

#all_of(*args) ⇒ Criteria

Adds a criterion to the criteria that specifies multiple expressions that all must match. This uses MongoDB’s $and operator under the covers.

Examples:

Match all provided expressions.

criteria.all_of(:name => value, :age.gt => 18)

Parameters:

  • Multiple (Array<Hash>)

    hash expressions.

Returns:

Since:

  • 2.3.0



35
36
37
38
39
40
41
42
43
44
# File 'lib/mongoid/criterion/inclusion.rb', line 35

def all_of(*args)
  clone.tap do |crit|
    unless args.empty?
      criterion = @selector["$and"] || []
      converted = BSON::ObjectId.convert(klass, args.flatten)
      expanded = converted.collect { |hash| hash.expand_complex_criteria }
      crit.selector["$and"] = criterion.concat(expanded)
    end
  end
end

#also_in(attributes = {}) ⇒ Criteria

Adds a criterion to the Criteria that specifies values where any can be matched in order to return results. This is similar to an SQL “IN” clause. The MongoDB conditional operator that will be used is “$in”. Any previously matching “$in” arrays will be unioned with new arguments.

Examples:

Adding the criterion.

criteria.in(:field => ["value1"]).also_in(:field => ["value2"])

Parameters:

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

    Name/value pairs any can match.

Returns:

  • (Criteria)

    A new criteria with the added selector.



58
59
60
# File 'lib/mongoid/criterion/inclusion.rb', line 58

def also_in(attributes = {})
  update_selector(attributes, "$in")
end

#and(selector = nil) ⇒ Criteria

Adds a criterion to the Criteria that specifies values that must be matched in order to return results. This is similar to a SQL “WHERE” clause. This is the actual selector that will be provided to MongoDB, similar to the Javascript object that is used when performing a find() in the MongoDB console.

Examples:

Adding the criterion.

criteria.and(:field1 => "value1", :field2 => 15)

Parameters:

  • selectior (Hash)

    Name/value pairs that all must match.

Returns:

  • (Criteria)

    A new criteria with the added selector.



74
75
76
# File 'lib/mongoid/criterion/inclusion.rb', line 74

def and(selector = nil)
  where(selector)
end

#any_of(*args) ⇒ Criteria Also known as: or

Adds a criterion to the Criteria that specifies a set of expressions to match if any of them return true. This is a $or query in MongoDB and is similar to a SQL OR. This is named #any_of and aliased “or” for readability.

Examples:

Adding the criterion.

criteria.any_of({ :field1 => "value" }, { :field2 => "value2" })

Parameters:

  • args (Array<Hash>)

    A list of name/value pairs any can match.

Returns:

  • (Criteria)

    A new criteria with the added selector.



89
90
91
92
93
94
95
96
# File 'lib/mongoid/criterion/inclusion.rb', line 89

def any_of(*args)
  clone.tap do |crit|
    criterion = @selector["$or"] || []
    converted = BSON::ObjectId.convert(klass, args.flatten)
    expanded = converted.collect { |hash| hash.expand_complex_criteria }
    crit.selector["$or"] = criterion.concat(expanded)
  end
end

#execute_or_raise(args) ⇒ Document+

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

Examples:

Execute or raise

criteria.execute_or_raise(id, criteria)

Parameters:

  • args (Object)

    The arguments passed.

  • criteria (Criteria)

    The criteria to execute.

Returns:

Raises:

Since:

  • 2.0.0



148
149
150
151
152
153
154
# File 'lib/mongoid/criterion/inclusion.rb', line 148

def execute_or_raise(args)
  (args[0].is_a?(Array) ? entries : from_map_or_db).tap do |result|
    if Mongoid.raise_not_found_error && !args.flatten.blank?
      raise Errors::DocumentNotFound.new(klass, args) if result._vacant?
    end
  end
end

#find(*args) ⇒ Document, Criteria

TODO:

Durran: DRY up duplicated code in a few places.

Find the matchind document in the criteria, either based on id or conditions.

Examples:

Find by an id.

criteria.find(BSON::ObjectId.new)

Find by multiple ids.

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

Conditionally find all matching documents.

criteria.find(:all, :conditions => { :title => "Sir" })

Conditionally find the first document.

criteria.find(:first, :conditions => { :title => "Sir" })

Conditionally find the last document.

criteria.find(:last, :conditions => { :title => "Sir" })

Parameters:

Returns:



124
125
126
127
128
129
130
131
132
133
# File 'lib/mongoid/criterion/inclusion.rb', line 124

def find(*args)
  type, crit = search(*args)
  case type
  when :first then crit.one
  when :last then crit.last
  when :ids then crit.execute_or_raise(args)
  else
    crit
  end
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(criteria)

Parameters:

Returns:

Since:

  • 2.2.1



167
168
169
170
# File 'lib/mongoid/criterion/inclusion.rb', line 167

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

#in(attributes = {}) ⇒ Criteria Also known as: any_in

Adds a criterion to the Criteria that specifies values where any can be matched in order to return results. This is similar to an SQL “IN” clause. The MongoDB conditional operator that will be used is “$in”.

Examples:

Adding the criterion.

criteria.in(:field => ["value1", "value2"])
criteria.in(:field1 => ["value1", "value2"], :field2 => ["value1"])

Parameters:

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

    Name/value pairs any can match.

Returns:

  • (Criteria)

    A new criteria with the added selector.



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

def in(attributes = {})
  update_selector(attributes, "$in", :&)
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



212
213
214
215
216
217
# File 'lib/mongoid/criterion/inclusion.rb', line 212

def includes(*relations)
  relations.flatten.each do |name|
    inclusions.push(klass.reflect_on_association(name))
  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



227
228
229
# File 'lib/mongoid/criterion/inclusion.rb', line 227

def inclusions
  @inclusions ||= []
end

#near(attributes = {}) ⇒ Criteria

Adds a criterion to the Criteria that specifies values to do geospacial searches by. The field must be indexed with the “2d” option.

Examples:

Adding the criterion.

criteria.near(:field1 => [30, -44])

Parameters:

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

    The fields with lat/long values.

Returns:

  • (Criteria)

    A new criteria with the added selector.



240
241
242
# File 'lib/mongoid/criterion/inclusion.rb', line 240

def near(attributes = {})
  update_selector(attributes, "$near")
end

#where(selector = nil) ⇒ Criteria

Adds a criterion to the Criteria that specifies values that must be matched in order to return results. This is similar to a SQL “WHERE” clause. This is the actual selector that will be provided to MongoDB, similar to the Javascript object that is used when performing a find() in the MongoDB console.

Examples:

Adding the criterion.

criteria.where(:field1 => "value1", :field2 => 15)

Parameters:

  • selector (Hash) (defaults to: nil)

    Name/value pairs where all must match.

Returns:

  • (Criteria)

    A new criteria with the added selector.



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'lib/mongoid/criterion/inclusion.rb', line 256

def where(selector = nil)
  clone.tap do |crit|
    selector = case selector
      when String then {"$where" => selector}
      else
        BSON::ObjectId.convert(klass, selector || {}, false).expand_complex_criteria
    end

    # @todo: Durran: 3.0.0: refactor the merging into separate strategies
    # to clean this funkiness up.
    selector.each_pair do |key, value|
      if crit.selector.has_key?(key)
        if key.mongoid_id?
          if crit.selector.has_key?("$and")
            crit.selector["$and"] << { key => value }
          elsif crit.selector[key] != value
            crit.selector["$and"] = [{ key => crit.selector.delete(key) }, { key => value }]
          end
        elsif crit.selector[key].respond_to?(:merge) && value.respond_to?(:merge)
          crit.selector[key] =
            crit.selector[key].merge(value) do |key, old, new|
              key == '$in' ? old & new : new
            end
        else
          crit.selector[key] = value
        end
      else
        crit.selector[key] = value
      end
    end
  end
end