module Mongoid::Criteria::Queryable::Mergeable

def __add__(criterion, operator)

Returns:
  • (Mergeable) - The new mergeable.

Parameters:
  • operator (String) -- The MongoDB operator.
  • criterion (Hash) -- The criteria.

Other tags:
    Example: Add the criterion. -

Other tags:
    Api: - private
def __add__(criterion, operator)
  with_strategy(:__add__, criterion, operator)
end

def __expanded__(criterion, outer, inner)

Returns:
  • (Mergeable) - The new mergeable.

Parameters:
  • inner (String) -- The inner MongoDB operator.
  • outer (String) -- The outer MongoDB operator.
  • criterion (Hash) -- The criteria.

Other tags:
    Example: Add the criterion. -

Other tags:
    Api: - private
def __expanded__(criterion, outer, inner)
  selection(criterion) do |selector, field, value|
    selector.store(field, { outer => { inner => value }})
  end
end

def __intersect__(criterion, operator)

Returns:
  • (Mergeable) - The new mergeable.

Parameters:
  • operator (String) -- The MongoDB operator.
  • criterion (Hash) -- The criteria.

Other tags:
    Example: Add the criterion. -

Other tags:
    Api: - private
def __intersect__(criterion, operator)
  with_strategy(:__intersect__, criterion, operator)
end

def __merge__(criterion)

Returns:
  • (Mergeable) - The cloned object.

Parameters:
  • criterion (Hash) -- The criteria.

Other tags:
    Example: Straight merge the expanded criterion. -

Other tags:
    Api: - private
def __merge__(criterion)
  selection(criterion) do |selector, field, value|
    selector.merge!(field.__expr_part__(value))
  end
end

def __multi__(criteria, operator)

Returns:
  • (Mergeable) - The new mergeable.

Parameters:
  • operator (String) -- The MongoDB operator.
  • criteria (Array) -- Multiple key/value pair

Other tags:
    Example: Add the criterion. -

Other tags:
    Api: - private
def __multi__(criteria, operator)
  clone.tap do |query|
    sel = query.selector
    criteria.flatten.each do |expr|
      next unless expr
      result_criteria = sel[operator] || []
      if expr.is_a?(Selectable)
        expr = expr.selector
      end
      normalized = _mongoid_expand_keys(expr)
      sel.store(operator, result_criteria.push(normalized))
    end
  end
end

def __override__(criterion, operator)

Returns:
  • (Mergeable) - The new mergeable.

Parameters:
  • operator (String) -- The MongoDB operator.
  • criterion (Hash | Criteria) -- The criteria.

Other tags:
    Example: Add the criterion. -

Other tags:
    Api: - private
def __override__(criterion, operator)
  if criterion.is_a?(Selectable)
    criterion = criterion.selector
  end
  selection(criterion) do |selector, field, value|
    expression = prepare(field, operator, value)
    existing = selector[field]
    if existing.respond_to?(:merge!)
      selector.store(field, existing.merge!(expression))
    else
      selector.store(field, expression)
    end
  end
end

def __union__(criterion, operator)

Returns:
  • (Mergeable) - The new mergeable.

Parameters:
  • operator (String) -- The MongoDB operator.
  • criterion (Hash) -- The criteria.

Other tags:
    Example: Add the criterion. -

Other tags:
    Api: - private
def __union__(criterion, operator)
  with_strategy(:__union__, criterion, operator)
end

def _mongoid_add_top_level_operation(operator, criteria)

Other tags:
    Api: - private
def _mongoid_add_top_level_operation(operator, criteria)
ten the criteria. The idea is that predicates in MongoDB
always hashes and are never arrays. This method additionally
ws Criteria instances as predicates.
flattening is existing Mongoid behavior but we could possibly
rid of it as applications can splat their predicates, or
ten if needed.
tap do |query|
= query.selector
goid_flatten_arrays(criteria).each do |criterion|
 criterion.is_a?(Selectable)
expr = _mongoid_expand_keys(criterion.selector)
se
expr = _mongoid_expand_keys(criterion)
d
 sel.empty?
sel.store(operator, [expr])
sif sel.keys == [operator]
sel.store(operator, sel[operator] + [expr])
se
operands = [sel.dup] + [expr]
sel.clear
sel.store(operator, operands)
d

def _mongoid_expand_keys(expr)

Returns:
  • (BSON::Document) - The expanded criteria.

Parameters:
  • expr (Hash) -- Criteria including Key instances.
def _mongoid_expand_keys(expr)
 expr.is_a?(Hash)
e ArgumentError, 'Argument must be a Hash'
 = BSON::Document.new
ach do |field, value|
d.__expr_part__(value.__expand_complex__, negating?).each do |k, v|
 existing = result[k]
if existing.is_a?(Hash)
  # Existing value is an operator.
  # If new value is also an operator, ensure there are no
  # conflicts and add
  if v.is_a?(Hash)
    # The new value is also an operator.
    # If there are no conflicts, combine the hashes, otherwise
    # add new conditions to top level with $and.
    if (v.keys & existing.keys).empty?
      existing.update(v)
    else
      raise NotImplementedError, 'Ruby does not allow same symbol operator with different values'
      result['$and'] ||= []
      result['$and'] << {k => v}
    end
  else
    # The new value is a simple value.
    # Transform the implicit equality to either $eq or $regexp
    # depending on the type of the argument. See
    # https://www.mongodb.com/docs/manual/reference/operator/query/eq/#std-label-eq-usage-examples
    # for the description of relevant server behavior.
    op = case v
    when Regexp, BSON::Regexp::Raw
      '$regex'
    else
      '$eq'
    end
    # If there isn't an $eq/$regex operator already in the
    # query, transform the new value into an operator
    # expression and add it to the existing hash. Otherwise
    # add the new condition with $and to the top level.
    if existing.key?(op)
      raise NotImplementedError, 'Ruby does not allow same symbol operator with different values'
      result['$and'] ||= []
      result['$and'] << {k => v}
    else
      existing.update(op => v)
    end
  end
else
  # Existing value is a simple value.
  # See the notes above about transformations to $eq/$regex.
  op = case existing
  when Regexp, BSON::Regexp::Raw
    '$regex'
  else
    '$eq'
  end
  if v.is_a?(Hash) && !v.key?(op)
    result[k] = {op => existing}.update(v)
  else
    raise NotImplementedError, 'Ruby does not allow same symbol operator with different values'
    result['$and'] ||= []
    result['$and'] << {k => v}
  end
end
se
result[k] = v
d

def _mongoid_flatten_arrays(array)

explicitly only expands Array objects and Array subclasses.
evaluates the criteria, which we do not want. Hence this method
Calling .flatten on an array which includes a Criteria instance
def _mongoid_flatten_arrays(array)
[]
g = array.dup
pending.empty?
 = pending.shift
tem.nil?
skip
f item.is_a?(Array)
nding += item

t << item

def and_with_operator(criterion, operator)

Returns:
  • (Criteria) - The resulting criteria.

Parameters:
  • operator (String) -- The MongoDB operator.
  • criterion (Hash) -- The criterion to add to the criteria.
def and_with_operator(criterion, operator)
  crit = self
  if criterion
    criterion.each_pair do |field, value|
      val = prepare(field, operator, value)
      # The prepare method already takes the negation into account. We
      # set negating to false here so that ``and`` doesn't also apply
      # negation and we have a double negative.
      crit.negating = false
      crit = crit.and(field => val)
    end
  end
  crit
end

def intersect

Returns:
  • (Mergeable) - The intersect flagged mergeable.

Other tags:
    Example: Use intersection on the next call. -
def intersect
  use(:__intersect__)
end

def override

Returns:
  • (Mergeable) - The override flagged mergeable.

Other tags:
    Example: Use override on the next call. -
def override
  use(:__override__)
end

def prepare(field, operator, value)

Returns:
  • (Object) - The serialized value.

Parameters:
  • value (Object) -- The value.
  • field (String) -- The name of the field.

Other tags:
    Example: Prepare the value. -

Other tags:
    Api: - private
def prepare(field, operator, value)
  unless operator =~ /exists|type|size/
    value = value.__expand_complex__
    field = field.to_s
    name = aliases[field] || field
    serializer = serializers[name]
    value = serializer ? serializer.evolve(value) : value
  end
  selection = { operator => value }
  negating? ? { "$not" => selection } : selection
end

def reset_strategies!

Returns:
  • (Criteria) - self.

Other tags:
    Example: Reset the strategies. -
def reset_strategies!
  self.strategy = nil
  self.negating = nil
  self
end

def union

Returns:
  • (Mergeable) - The union flagged mergeable.

Other tags:
    Example: Use union on the next call. -
def union
  use(:__union__)
end

def use(strategy)

Returns:
  • (Mergeable) - The existing mergeable.

Parameters:
  • strategy (Symbol) -- The strategy to use.

Other tags:
    Example: Use intersection. -

Other tags:
    Api: - private
def use(strategy)
  tap do |mergeable|
    mergeable.strategy = strategy
  end
end

def with_strategy(strategy, criterion, operator)

Returns:
  • (Mergeable) - The cloned query.

Parameters:
  • operator (String) -- The MongoDB operator.
  • criterion (Object) -- The criterion to add.
  • strategy (Symbol) -- The name of the strategy method.

Other tags:
    Example: Add criterion with a strategy. -

Other tags:
    Api: - private
def with_strategy(strategy, criterion, operator)
  selection(criterion) do |selector, field, value|
    selector.store(
      field,
      selector[field].send(strategy, prepare(field, operator, value))
    )
  end
end