Class: Moped::Query

Inherits:
Object show all
Includes:
Enumerable
Defined in:
lib/moped/query.rb

Overview

The Query class encapsulates all of the logic related to building selectors for querying, updating, or removing documents in a collection.

Examples:

people = db[:people]
people.find.entries # => [{id: 1}, {id: 2}, {id: 3}, {id: 4}, {id: 5}]
people.find.skip(2).first # => { id: 3 }
people.find.skip(2).update(name: "John")
people.find.skip(2).first # => { id: 3, name: "John" }

people.find(name: nil).update_all(name: "Unknown")
people.find.one # => { id: 5, name: "Unknown" }
people.find.first # => { id: 5, name: "Unknown" }
people.find.select(name: 0).first # => { id: 5 }
people.find(name: "Unknown").remove_all
people.find.count # => 1

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(collection, selector) ⇒ Query

Initialize the query.

Examples:

Initialize the query.

Query.new(collection, selector)

Parameters:

  • collection (Collection)

    The query’s collection.

  • selector (Hash)

    The query’s selector.

Since:

  • 1.0.0



151
152
153
154
155
156
157
158
# File 'lib/moped/query.rb', line 151

def initialize(collection, selector)
  @collection, @selector = collection, selector
  @operation = Protocol::Query.new(
    collection.database.name,
    collection.name,
    selector
  )
end

Instance Attribute Details

#collectionObject (readonly)

Returns the value of attribute collection.



25
26
27
# File 'lib/moped/query.rb', line 25

def collection
  @collection
end

#collection The collection to execute the query on.(Thecollectiontoexecutethequeryon.) ⇒ Object (readonly)



25
# File 'lib/moped/query.rb', line 25

attr_reader :collection, :operation, :selector

#operationObject (readonly)

Returns the value of attribute operation.



25
26
27
# File 'lib/moped/query.rb', line 25

def operation
  @operation
end

#operation The query operation.(Thequeryoperation.) ⇒ Object (readonly)



25
# File 'lib/moped/query.rb', line 25

attr_reader :collection, :operation, :selector

#selectorObject (readonly)

Returns the value of attribute selector.



25
26
27
# File 'lib/moped/query.rb', line 25

def selector
  @selector
end

#selector The query selector.(Thequeryselector.) ⇒ Object (readonly)



25
# File 'lib/moped/query.rb', line 25

attr_reader :collection, :operation, :selector

Instance Method Details

#countInteger

Get the count of matching documents in the query.

Examples:

Get the count.

db[:people].find.count

Returns:

  • (Integer)

    The number of documents that match the selector.

Since:

  • 1.0.0



35
36
37
38
39
40
41
# File 'lib/moped/query.rb', line 35

def count
  result = collection.database.command(
    count: collection.name,
    query: selector
  )
  result["n"].to_i
end

#distinct(key) ⇒ Array<Object ] The distinct values.

Get the distinct values in the collection for the provided key.

Examples:

Get the distinct values.

db[:people].find.distinct(:name)

Parameters:

Returns:

Since:

  • 1.0.0



53
54
55
56
57
58
59
60
# File 'lib/moped/query.rb', line 53

def distinct(key)
  result = collection.database.command(
    distinct: collection.name,
    key: key.to_s,
    query: selector
  )
  result["values"]
end

#each {|document| ... } ⇒ Enumerator

Iterate through documents matching the query’s selector.

Examples:

Iterate over the matching documents.

db[:people].find.each do |doc|
  #...
end

Yield Parameters:

  • document (Hash)

    each matching document

Returns:

  • (Enumerator)

    The enumerator.

Since:

  • 1.0.0



74
75
76
77
78
79
80
81
# File 'lib/moped/query.rb', line 74

def each
  cursor = Cursor.new(session, operation)
  enum = cursor.to_enum
  enum.each do |document|
    yield document
  end if block_given?
  enum
end

#explainHash

Explain the current query.

Examples:

Explain the query.

db[:people].find.explain

Returns:

  • (Hash)

    The explain document.

Since:

  • 1.0.0



91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/moped/query.rb', line 91

def explain
  explanation = operation.selector.dup
  hint = explanation["$hint"]
  sort = explanation["$orderby"]
  explanation = {
    "$query" => selector,
    "$explain" => true,
  }
  explanation["$orderby"] = sort if sort
  explanation["$hint"] = hint if hint
  Query.new(collection, explanation).limit(-(operation.limit.abs)).each { |doc| return doc }
end

#firstHash Also known as: one

Get the first matching document.

Examples:

Get the first matching document.

db[:people].find.first

Returns:

  • (Hash)

    The first document that matches the selector.

Since:

  • 1.0.0



112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/moped/query.rb', line 112

def first
  reply = session.context.query(
    operation.database,
    operation.collection,
    operation.selector,
    fields: operation.fields,
    flags: operation.flags,
    skip: operation.skip,
    limit: -1
  )
  reply.documents.first
end

#hint(hint) ⇒ Query

Apply an index hint to the query.

Examples:

Apply an index hint.

db[:people].find.hint("$natural" => 1)

Parameters:

  • hint (Hash)

    The index hint.

Returns:

Since:

  • 1.0.0



136
137
138
139
140
# File 'lib/moped/query.rb', line 136

def hint(hint)
  operation.selector = { "$query" => selector } unless operation.selector["$query"]
  operation.selector["$hint"] = hint
  self
end

#limit(limit) ⇒ Query

Set the query’s limit.

Examples:

Set the limit.

db[:people].find.limit(20)

Parameters:

  • limit (Integer)

    The number of documents to limit.

Returns:

Since:

  • 1.0.0



170
171
172
173
# File 'lib/moped/query.rb', line 170

def limit(limit)
  operation.limit = limit
  self
end

#modify(change, options = {}) ⇒ Hash

Execute a $findAndModify on the query.

Examples:

Find and modify a document, returning the original.

db[:bands].find.modify({ "$inc" => { likes: 1 }})

Find and modify a document, returning the updated document.

db[:bands].find.modify({ "$inc" => { likes: 1 }}, new: true)

Find and return a document, removing it from the database.

db[:bands].find.modify({}, remove: true)

Find and return a document, upserting if no match found.

db[:bands].find.modify({}, upsert: true, new: true)

Parameters:

  • change (Hash)

    The changes to make to the document.

  • options (Hash) (defaults to: {})

    The options.

Options Hash (options):

  • :new (Object)

    Set to true if you want to return the updated document.

  • :remove (Object)

    Set to true if the document should be deleted.

  • :upsert (Object)

    Set to true if you want to upsert

Returns:

  • (Hash)

    The document.

Since:

  • 1.0.0



199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/moped/query.rb', line 199

def modify(change, options = {})
  command = {
    findAndModify: collection.name,
    query: selector
  }.merge(options)

  command[:sort] = operation.selector["$orderby"] if operation.selector["$orderby"]
  command[:fields] = operation.fields if operation.fields
  command[:update] = change unless options[:remove]

  result = session.with(consistency: :strong) do |sess|
    sess.command(command)["value"]
  end

  # Keeping moped compatibility with mongodb >= 2.2.0-rc0
  options[:upsert] && !result ? [] : result
end

#removeHash?

Remove a single document matching the query’s selector.

Examples:

Remove a single document.

db[:people].find(name: "John").remove

Returns:

  • (Hash, nil)

    If in safe mode the last error result.

Since:

  • 1.0.0



225
226
227
228
229
230
231
232
233
234
# File 'lib/moped/query.rb', line 225

def remove
  session.with(consistency: :strong) do |session|
    session.context.remove(
      operation.database,
      operation.collection,
      operation.selector,
      flags: [ :remove_first ]
    )
  end
end

#remove_allHash?

Remove multiple documents matching the query’s selector.

Examples:

Remove all matching documents.

db[:people].find(name: "John").remove_all

Returns:

  • (Hash, nil)

    If in safe mode the last error result.

Since:

  • 1.0.0



244
245
246
247
248
249
250
251
252
# File 'lib/moped/query.rb', line 244

def remove_all
  session.with(consistency: :strong) do |session|
    session.context.remove(
      operation.database,
      operation.collection,
      operation.selector
    )
  end
end

#select(select) ⇒ Query

Set the fields to include or exclude from the query.

Examples:

Select the fields to include or exclude.

db[:people].find.select(name: 1).one # => { name: "John" }

Parameters:

  • select (Hash)

    The inclusions or exclusions.

Returns:

Since:

  • 1.0.0



264
265
266
267
# File 'lib/moped/query.rb', line 264

def select(select)
  operation.fields = select
  self
end

#skip(skip) ⇒ Query

Set the number of documents to skip.

Examples:

Set the number to skip.

db[:people].find.skip(20)

Parameters:

  • skip (Integer)

    The number of documents to skip.

Returns:

Since:

  • 1.0.0



279
280
281
282
# File 'lib/moped/query.rb', line 279

def skip(skip)
  operation.skip = skip
  self
end

#sort(sort) ⇒ Query

Set the sort order for the query.

Examples:

Set the sort order.

db[:people].find.sort(name: 1, age: -1).one

Parameters:

  • sort (Hash)

    The order as key/(1/-1) pairs.

Returns:

Since:

  • 1.0.0



294
295
296
297
# File 'lib/moped/query.rb', line 294

def sort(sort)
  operation.selector = { "$query" => selector, "$orderby" => sort }
  self
end

#update(change, flags = nil) ⇒ Hash?

Update a single document matching the query’s selector.

Examples:

Update the first matching document.

db[:people].find(_id: 1).update(name: "John")

Parameters:

  • change (Hash)

    The changes to make to the document

  • flags (Array) (defaults to: nil)

    An array of operation flags. Valid values are: :multi and :upsert

Returns:

  • (Hash, nil)

    If in safe mode the last error result.

Since:

  • 1.0.0



311
312
313
314
315
316
317
318
319
320
321
# File 'lib/moped/query.rb', line 311

def update(change, flags = nil)
  session.with(consistency: :strong) do |session|
    session.context.update(
      operation.database,
      operation.collection,
      operation.selector["$query"] || operation.selector,
      change,
      flags: flags
    )
  end
end

#update_all(change) ⇒ Hash?

Update multiple documents matching the query’s selector.

Examples:

Update multiple documents.

db[:people].find(name: "John").update_all(name: "Mary")

Parameters:

  • change (Hash)

    The changes to make to the documents

Returns:

  • (Hash, nil)

    If in safe mode the last error result.

Since:

  • 1.0.0



333
334
335
# File 'lib/moped/query.rb', line 333

def update_all(change)
  update(change, [ :multi ])
end

#upsert(change) ⇒ Hash?

Update an existing document with change, otherwise create one.

Examples:

Upsert the changes.

db[:people].find.entries # => { name: "John" }
db[:people].find(name: "John").upsert(name: "James")
db[:people].find.entries # => { name: "James" }
db[:people].find(name: "John").upsert(name: "Mary")
db[:people].find.entries # => [{ name: "James" }, { name: "Mary" }]

Parameters:

  • change (Hash)

    The changes to make to the the document.

Returns:

  • (Hash, nil)

    If in safe mode the last error result.

Since:

  • 1.0.0



351
352
353
# File 'lib/moped/query.rb', line 351

def upsert(change)
  update(change, [ :upsert ])
end