module Origin::Aggregable

Provides a DSL around crafting aggregation framework commands.

@since 2.0.0

Attributes

aggregating[W]

@attribute [rw] aggregating Flag for whether or not we are aggregating.

pipeline[R]

@attribute [r] pipeline The aggregation pipeline.

Public Instance Methods

aggregating?() click to toggle source

Has the aggregable enter an aggregation state. Ie, are only aggregation operations allowed at this point on.

@example Is the aggregable aggregating?

aggregable.aggregating?

@return [ true, false ] If the aggregable is aggregating.

@since 2.0.0

# File lib/origin/aggregable.rb, line 24
def aggregating?
  !!@aggregating
end
group(operation) click to toggle source

Add a group ($group) operation to the aggregation pipeline.

@example Add a group operation being verbose.

aggregable.group(count: { "$sum" => 1 }, max: { "$max" => "likes" })

@example Add a group operation using symbol shortcuts.

aggregable.group(:count.sum => 1, :max.max => "likes")

@param [ Hash ] operation The group operation.

@return [ Aggregable ] The aggregable.

@since 2.0.0

# File lib/origin/aggregable.rb, line 41
def group(operation)
  aggregation(operation) do |pipeline|
    pipeline.group(operation)
  end
end
project(operation = nil) click to toggle source

Add a projection ($project) to the aggregation pipeline.

@example Add a projection to the pipeline.

aggregable.project(author: 1, name: 0)

@param [ Hash ] criterion The projection to make.

@return [ Aggregable ] The aggregable.

@since 2.0.0

# File lib/origin/aggregable.rb, line 65
def project(operation = nil)
  aggregation(operation) do |pipeline|
    pipeline.project(operation)
  end
end
unwind(field) click to toggle source

Add an unwind ($unwind) to the aggregation pipeline.

@example Add an unwind to the pipeline.

aggregable.unwind(:field)

@param [ String, Symbol ] field The name of the field to unwind.

@return [ Aggregable ] The aggregable.

@since 2.0.0

# File lib/origin/aggregable.rb, line 81
def unwind(field)
  aggregation(field) do |pipeline|
    pipeline.unwind(field)
  end
end

Private Instance Methods

aggregation(operation) { |pipeline| ... } click to toggle source

Add the aggregation operation.

@api private

@example Aggregate on the operation.

aggregation(operation) do |pipeline|
  pipeline.push("$project" => operation)
end

@param [ Hash ] operation The operation for the pipeline.

@return [ Aggregable ] The cloned aggregable.

@since 2.0.0

# File lib/origin/aggregable.rb, line 103
def aggregation(operation)
  return self unless operation
  clone.tap do |query|
    unless aggregating?
      query.pipeline.concat(query.selector.to_pipeline)
      query.pipeline.concat(query.options.to_pipeline)
      query.aggregating = true
    end
    yield(query.pipeline)
  end
end