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

#load_ids(key) ⇒ Array<String, BSON::ObjectId>

Loads an array of ids only for the current criteria. Used by eager loading to determine the documents to load.

Examples:

Load the related ids.

criteria.load_ids("person_id")

Parameters:

  • key (String)

    The id or foriegn key string.

Returns:

Since:

  • 2.2.0



242
243
244
# File 'lib/mongoid/criterion/inclusion.rb', line 242

def load_ids(key)
  driver.find(selector, { :fields => { key => 1 }}).map { |doc| doc[key] }
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.



255
256
257
# File 'lib/mongoid/criterion/inclusion.rb', line 255

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.



271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
# File 'lib/mongoid/criterion/inclusion.rb', line 271

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 }
          else
            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