class Mongocore::Query

Attributes

cache[RW]

# # # # # # # The Query class keeps the cursor and handles the connection with the underlying MongoDB database. A new query is created every time you call find, sort, limit, count, update, scopes and associations.

Every query can be chained, but only one find is ever done to the database, it's only the parameters that change.

collection[RW]

# # # # # # # The Query class keeps the cursor and handles the connection with the underlying MongoDB database. A new query is created every time you call find, sort, limit, count, update, scopes and associations.

Every query can be chained, but only one find is ever done to the database, it's only the parameters that change.

colname[RW]

# # # # # # # The Query class keeps the cursor and handles the connection with the underlying MongoDB database. A new query is created every time you call find, sort, limit, count, update, scopes and associations.

Every query can be chained, but only one find is ever done to the database, it's only the parameters that change.

model[RW]

# # # # # # # The Query class keeps the cursor and handles the connection with the underlying MongoDB database. A new query is created every time you call find, sort, limit, count, update, scopes and associations.

Every query can be chained, but only one find is ever done to the database, it's only the parameters that change.

options[RW]

# # # # # # # The Query class keeps the cursor and handles the connection with the underlying MongoDB database. A new query is created every time you call find, sort, limit, count, update, scopes and associations.

Every query can be chained, but only one find is ever done to the database, it's only the parameters that change.

query[RW]

# # # # # # # The Query class keeps the cursor and handles the connection with the underlying MongoDB database. A new query is created every time you call find, sort, limit, count, update, scopes and associations.

Every query can be chained, but only one find is ever done to the database, it's only the parameters that change.

Public Class Methods

new(m, q = {}, o = {}) click to toggle source

Mongocore query initializer

# File lib/mongocore/query.rb, line 16
def initialize(m, q = {}, o = {})

  # Storing model class. The instance can be found in options[:source]
  @model = m

  # The model name is singular, the collection name is plural
  @colname = m.to_s.downcase.pluralize.to_sym

  # Storing the Mongo::Collection object
  @collection = Mongocore.db[@colname]

  # Default options
  o[:source] ||= nil
  o[:chain] ||= []
  o[:skip] ||= 0
  o[:limit] ||= 0
  o[:sort] ||= Mongocore.sort.dup
  o[:projection] ||= {}

  # Storing query and options
  @query, @options = @model.schema.ids(hashify(q)), o

  # Set up cache
  @cache = Mongocore::Cache.new(self)
end

Public Instance Methods

all() click to toggle source

Return all documents

# File lib/mongocore/query.rb, line 111
def all
  fetch(:to_a).map{|d| modelize(d)}
end
as_json(o = {}) click to toggle source

JSON format

# File lib/mongocore/query.rb, line 197
def as_json(o = {})
  all
end
count() click to toggle source

Count. Returns the number of documents as an integer

# File lib/mongocore/query.rb, line 89
def count
  counter || fetch(:count)
end
counter(s = @options[:source], c = @options[:chain]) click to toggle source

Check if there's a corresponding counter for this count

# File lib/mongocore/query.rb, line 94
def counter(s = @options[:source], c = @options[:chain])
  s.send(%{#{@colname}#{c.present? ? "_#{c.join('_')}" : ''}_count}) rescue nil
end
cursor() click to toggle source

Cursor

# File lib/mongocore/query.rb, line 54
def cursor
  o = @options.dup

  # Remove blank options
  o.delete(:skip) if o[:skip] < 1
  o.delete(:limit) if o[:limit] < 1
  o.delete(:sort) if o[:sort].empty?
  o.delete(:projection) if o[:projection].empty?

  # Return view
  @collection.find(@query, o)
end
delete() click to toggle source

Delete

# File lib/mongocore/query.rb, line 84
def delete
  @collection.delete_one(@query).ok?
end
each() { |modelize(r)| ... } click to toggle source

Each

# File lib/mongocore/query.rb, line 152
def each(&block)
  cursor.each{|r| yield(modelize(r))}
end
each_with_index() { |modelize(r), n| ... } click to toggle source

Each with index

# File lib/mongocore/query.rb, line 157
def each_with_index(&block)
  cursor.each_with_index{|r, n| yield(modelize(r), n)}
end
each_with_object(obj) { |modelize(r), o| ... } click to toggle source

Each with object

# File lib/mongocore/query.rb, line 162
def each_with_object(obj, &block)
  cursor.each_with_object(obj){|r, o| yield(modelize(r), o)}
end
fetch(t) click to toggle source

Fetch docs, pass type :first, :to_a or :count

# File lib/mongocore/query.rb, line 144
def fetch(t)
  cache.get(t) if Mongocore.cache

  # Fetch from mongodb and add to cache
  cursor.send(t).tap{|r| cache.set(t, r) if Mongocore.cache}
end
fields(o = {})
Alias for: projection
find(q = {}, o = {}) click to toggle source

Find. Returns a Mongocore::Query

# File lib/mongocore/query.rb, line 43
def find(q = {}, o = {})
  self.class.new(@model, @query.merge(hashify(q)), @options.merge(o))
end
Also aliased as: where
first(*args) click to toggle source

Return first document

# File lib/mongocore/query.rb, line 99
def first(*args)
  modelize(find(*args).fetch(:first))
end
hashify(q) click to toggle source

Convert string query to hash

# File lib/mongocore/query.rb, line 49
def hashify(q)
  q.is_a?(Hash) ? q : {:_id => q}
end
insert(a) click to toggle source

Insert

# File lib/mongocore/query.rb, line 68
def insert(a)
  @collection.insert_one(a.delete_if{|k, v| v.nil?})
end
key() click to toggle source

Cache key

# File lib/mongocore/query.rb, line 202
def key
  @key ||= "#{@model}#{@query.sort}#{@options.values}"
end
last(*args) click to toggle source

Return last document Uses the opposite of the Mongocore.sort setting

# File lib/mongocore/query.rb, line 105
def last(*args)
  a = Mongocore.sort.any? ? Mongocore.sort.dup : {:_id => 1}
  sort(a.each{|k, v| a[k] = v * -1}).limit(1).first(*args)
end
limit(n = 1) click to toggle source

Limit

# File lib/mongocore/query.rb, line 178
def limit(n = 1)
  @options[:limit] = n
  find(@query, @options)
end
map() { |modelize(r)| ... } click to toggle source

Map

# File lib/mongocore/query.rb, line 167
def map(&block)
  cursor.map{|r| yield(modelize(r))}
end
method_missing(name, *arguments, &block) click to toggle source

Call and return the scope if it exists

Calls superclass method
# File lib/mongocore/query.rb, line 207
def method_missing(name, *arguments, &block)
  if @model.schema.scopes.has_key?(name)
    @options[:chain] << name
    return @model.send(name, @query, @options)
  end
  super
end
modelize(doc) click to toggle source

BSON::Document to model

# File lib/mongocore/query.rb, line 139
def modelize(doc)
  doc ? @model.new(doc.to_hash) : nil
end
paginate(o = {}) click to toggle source

Paginate

# File lib/mongocore/query.rb, line 116
def paginate(o = {})
  # Get total count before applying pagination
  total = fetch(:count)

  # Set page, defaults to 1
  o[:page] = o[:page].to_i
  o[:page] = 1 if o[:page] < 1

  # Set results per page, defaults to 20 in Mongocore.per_page setting
  o[:per_page] = o[:per_page].to_i
  o[:per_page] = Mongocore.per_page if o[:per_page] < 1

  # Skip results
  @options[:skip] = o[:per_page] * (o[:page] - 1)

  # Apply limit
  @options[:limit] = o[:per_page]

  # Fetch the result as array
  all.tap{|r| r.total = total}
end
projection(o = {}) click to toggle source

Projection

# File lib/mongocore/query.rb, line 190
def projection(o = {})
  @options[:projection].merge!(o)
  find(@query, @options)
end
Also aliased as: fields
skip(n = 0) click to toggle source

Skip

# File lib/mongocore/query.rb, line 184
def skip(n = 0)
  @options[:skip] = n
  find(@query, @options)
end
sort(o = {}) click to toggle source

Sort

# File lib/mongocore/query.rb, line 172
def sort(o = {})
  (@options[:sort] ||= {}).merge!(o)
  find(@query, @options)
end
update(a) click to toggle source

Update

# File lib/mongocore/query.rb, line 73
def update(a)
  # We do $set on non nil, $unset on nil
  u = {
    :$set => a.select{|k, v| !v.nil?}, :$unset => a.select{|k, v| v.nil?}
  }.delete_if{|k, v| v.empty?}

  # Update the collection
  @collection.update_one(@query, u, :upsert => true)
end
where(q = {}, o = {})
Alias for: find