module Origin::Optional

The optional module includes all behaviour that has to do with extra options surrounding queries, like skip, limit, sorting, etc.

Attributes

options[RW]

@attribute [rw] options The query options.

Private Class Methods

forwardables() click to toggle source

Get the methods on the optional that can be forwarded to from a model.

@example Get the forwardable methods.

Optional.forwardables

@return [ Array<Symbol> ] The names of the forwardable methods.

@since 1.0.0

# File lib/origin/optional.rb, line 386
def forwardables
  public_instance_methods(false) - [ :options, :options= ]
end

Public Instance Methods

asc(*fields)
Alias for: ascending
ascending(*fields) click to toggle source

Add ascending sorting options for all the provided fields.

@example Add ascending sorting.

optional.ascending(:first_name, :last_name)

@param [ Array<Symbol> ] fields The fields to sort.

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 21
def ascending(*fields)
  sort_with_list(*fields, 1)
end
Also aliased as: asc
batch_size(value = nil) click to toggle source

Adds the option for telling MongoDB how many documents to retrieve in it's batching.

@example Apply the batch size options.

optional.batch_size(500)

@param [ Integer ] value The batch size.

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 39
def batch_size(value = nil)
  option(value) { |options| options.store(:batch_size, value) }
end
comment(comment = nil) click to toggle source

Associate a comment with the query.

@example Add a comment.

optional.comment('slow query')

@note Set profilingLevel to 2 and the comment will be logged in the profile

collection along with the query.

@param [ String ] comment The comment to be associated with the query.

@return [ Optional ] The cloned optional.

@since 2.2.0

# File lib/origin/optional.rb, line 282
def comment(comment = nil)
  clone.tap do |query|
    query.options.store(:comment, comment)
  end
end
cursor_type(type) click to toggle source

Set the cursor type.

@example Set the cursor type.

optional.cursor_type(:tailable)
optional.cursor_type(:tailable_await)

@note The cursor can be type :tailable or :tailable_await.

@param [ Symbol ] type The type of cursor to create.

@return [ Optional ] The cloned optional.

@since 2.2.0

# File lib/origin/optional.rb, line 301
def cursor_type(type)
  clone.tap { |query| query.options.store(:cursor_type, type) }
end
desc(*fields)
Alias for: descending
descending(*fields) click to toggle source

Add descending sorting options for all the provided fields.

@example Add descending sorting.

optional.descending(:first_name, :last_name)

@param [ Array<Symbol> ] fields The fields to sort.

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 53
def descending(*fields)
  sort_with_list(*fields, -1)
end
Also aliased as: desc
hint(value = nil) click to toggle source

Add an index hint to the query options.

@example Add an index hint.

optional.hint("$natural" => 1)

@param [ Hash ] value The index hint.

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 70
def hint(value = nil)
  option(value) { |options| options.store(:hint, value) }
end
limit(value = nil) click to toggle source

Add the number of documents to limit in the returned results.

@example Limit the number of returned documents.

optional.limit(20)

@param [ Integer ] value The number of documents to return.

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 84
def limit(value = nil)
  option(value) do |options, query|
    val = value.to_i
    options.store(:limit, val)
    query.pipeline.push("$limit" => val) if aggregating?
  end
end
max_scan(value = nil) click to toggle source

Adds the option to limit the number of documents scanned in the collection.

@example Add the max scan limit.

optional.max_scan(1000)

@param [ Integer ] value The max number of documents to scan.

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 103
def max_scan(value = nil)
  option(value) { |options| options.store(:max_scan, value) }
end
no_timeout() click to toggle source

Tell the query not to timeout.

@example Tell the query not to timeout.

optional.no_timeout

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 115
def no_timeout
  clone.tap { |query| query.options.store(:timeout, false) }
end
offset(value = nil)
Alias for: skip
only(*args) click to toggle source

Limits the results to only contain the fields provided.

@example Limit the results to the provided fields.

optional.only(:name, :dob)

@param [ Array<Symbol> ] args The fields to return.

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 129
def only(*args)
  args = args.flatten
  option(*args) do |options|
    options.store(
      :fields, args.inject(options[:fields] || {}){ |sub, field| sub.tap { sub[field] = 1 }}
    )
  end
end
order(*spec)
Alias for: order_by
order_by(*spec) click to toggle source

Adds sorting criterion to the options.

@example Add sorting options via a hash with integer directions.

optional.order_by(name: 1, dob: -1)

@example Add sorting options via a hash with symbol directions.

optional.order_by(name: :asc, dob: :desc)

@example Add sorting options via a hash with string directions.

optional.order_by(name: "asc", dob: "desc")

@example Add sorting options via an array with integer directions.

optional.order_by([[ name, 1 ], [ dob, -1 ]])

@example Add sorting options via an array with symbol directions.

optional.order_by([[ name, :asc ], [ dob, :desc ]])

@example Add sorting options via an array with string directions.

optional.order_by([[ name, "asc" ], [ dob, "desc" ]])

@example Add sorting options with keys.

optional.order_by(:name.asc, :dob.desc)

@example Add sorting options via a string.

optional.order_by("name ASC, dob DESC")

@param [ Array, Hash, String ] spec The sorting specification.

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 169
def order_by(*spec)
  option(spec) do |options, query|
    spec.compact.each do |criterion|
      criterion.__sort_option__.each_pair do |field, direction|
        add_sort_option(options, field, direction)
      end
      query.pipeline.push("$sort" => options[:sort]) if aggregating?
    end
  end
end
Also aliased as: order
reorder(*spec) click to toggle source

Instead of merging the order criteria, use this method to completely replace the existing ordering with the provided.

@example Replace the ordering.

optional.reorder(name: :asc)

@param [ Array, Hash, String ] spec The sorting specification.

@return [ Optional ] The cloned optional.

@since 2.1.0

# File lib/origin/optional.rb, line 192
def reorder(*spec)
  options.delete(:sort)
  order_by(*spec)
end
skip(value = nil) click to toggle source

Add the number of documents to skip.

@example Add the number to skip.

optional.skip(100)

@param [ Integer ] value The number to skip.

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 207
def skip(value = nil)
  option(value) do |options, query|
    val = value.to_i
    options.store(:skip, val)
    query.pipeline.push("$skip" => val) if aggregating?
  end
end
Also aliased as: offset
slice(criterion = nil) click to toggle source

Limit the returned results via slicing embedded arrays.

@example Slice the returned results.

optional.slice(aliases: [ 0, 5 ])

@param [ Hash ] criterion The slice options.

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 226
def slice(criterion = nil)
  option(criterion) do |options|
    options.__union__(
      fields: criterion.inject({}) do |option, (field, val)|
        option.tap { |opt| opt.store(field, { "$slice" => val }) }
      end
    )
  end
end
snapshot() click to toggle source

Tell the query to operate in snapshot mode.

@example Add the snapshot option.

optional.snapshot

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 244
def snapshot
  clone.tap do |query|
    query.options.store(:snapshot, true)
  end
end
without(*args) click to toggle source

Limits the results to only contain the fields not provided.

@example Limit the results to the fields not provided.

optional.without(:name, :dob)

@param [ Array<Symbol> ] args The fields to ignore.

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 260
def without(*args)
  args = args.flatten
  option(*args) do |options|
    options.store(
      :fields, args.inject(options[:fields] || {}){ |sub, field| sub.tap { sub[field] = 0 }}
    )
  end
end

Private Instance Methods

add_sort_option(options, field, direction) click to toggle source

Add a single sort option.

@api private

@example Add a single sort option.

optional.add_sort_option({}, :name, 1)

@param [ Hash ] options The options. @param [ String ] field The field name. @param [ Integer ] direction The sort direction.

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 321
def add_sort_option(options, field, direction)
  if driver == :mongo1x
    sorting = (options[:sort] || []).dup
    sorting.push([ field, direction ])
    options.store(:sort, sorting)
  else
    sorting = (options[:sort] || {}).dup
    sorting[field] = direction
    options.store(:sort, sorting)
  end
end
option(*args) { |options, query| ... } click to toggle source

Take the provided criterion and store it as an option in the query options.

@api private

@example Store the option.

optional.option({ skip: 10 })

@param [ Array ] args The options.

@return [ Queryable ] The cloned queryable.

@since 1.0.0

# File lib/origin/optional.rb, line 346
def option(*args)
  clone.tap do |query|
    unless args.compact.empty?
      yield(query.options, query)
    end
  end
end
sort_with_list(*fields, direction) click to toggle source

Add multiple sort options at once.

@api private

@example Add multiple sort options.

optional.sort_with_list(:name, :dob, 1)

@param [ Array<String> ] fields The field names. @param [ Integer ] direction The sort direction.

@return [ Optional ] The cloned optional.

@since 1.0.0

# File lib/origin/optional.rb, line 367
def sort_with_list(*fields, direction)
  option(fields) do |options, query|
    fields.flatten.compact.each do |field|
      add_sort_option(options, field, direction)
    end
    query.pipeline.push("$sort" => options[:sort]) if aggregating?
  end
end