How to query MongoDB directly from Ruby instead of

2019-02-01 07:07发布

问题:

I am writing a migration for a Rails application that uses MongoDB and Mongoid. My migration currently uses my models that use Mongoid to query and update records, but the performance is sub-par. I am essentially updating all records in a large collection and making n+20 queries. I killed the migration after taking an hour to run locally (and didn't finish). I would like to be able to run raw queries to mongo without too much effort. I'm assuming there is some way to access a mongo driver from Mongoid since Mongoid has already loaded a connection to the database. How can I access the database to run my update queries direcly?

回答1:

If you're using Mongoid 3, it provides easy access to its MongoDB driver: Moped. Here's an example of accessing some raw data without using Models to access the data:

db = Mongoid::Sessions.default

# inserting a new document
collection = db[:collection_name]
collection.insert(name: 'my new document')

# finding a document
doc = collection.find(name: 'my new document').first

# iterating over all documents in a collection
collection.find.each do |document|
  puts document.inspect
end


回答2:

For Mongoid 5:

db = Mongoid::Clients.default

collection = db[:collection_name]

Now we can perform queries on the collection



回答3:

Here how you do it (This would work for 2+ and 3+ as well)

1) All your Model exhibit this behavior you have include Mongoid::Document inside all your model so technically each document is mapped in monogodb thru moped or mongodb-ruby driver via mongoid

so If you have model Like

class PerformerSource 
  include Mongoid::Document
  ## Definition

end

Now you can run Mongo Query using the driver (Moped or Mongodb-ruby driver) like this

PerformerSource.collection.insert("something")
## where something is json document you want to insert

This would give u the moped (if using mongoid 3) connection for that document

2) You can also do it something like this

 Mongoid::Sessions.default.collections.find { |document| document.name == "performer_sources"}.insert("something")

How to more on mongo query and how mongoid map those using moped u can follow this section of querying where it describe how query is acheived internally via moped

Hope this help



回答4:

The short answer is Moped. This is the lower-level API that Mongoid is built upon and will be available if you already use Mongoid. The Moped API is a thin wrapper around the raw MongoDB operations. The documentation here: http://mongoid.org/en/moped/docs/driver.html should be useful.



回答5:

Like anyone has mention here , your answer is Moped. Here is my example for a ruby script (simple file test.rb)

  1. Define a mongoid.yml (in this case , at localhost)

development: sessions: default: database: test_development hosts: - localhost:27017 options: 2. Set load config and test collection

#!/usr/bin/env ruby
require 'mongoid'

Mongoid.load!("path/to/file/mongoid.yml",:development) # :development corresponds to mongoid.yml first line environment
db = Mongoid::Sessions.default
puts "Collection documents count :> #{db[:collection].find.count}"


回答6:

If you using mongoid 5(five) I would recommend using this.

Item.collection.update_one({_id:  BSON::ObjectId('55512b7070722d22d3050000')}, '$set' => { 'category_name': 'Test' })

The trick to this is the BSON::ObjectID. This is like in the mongo query if you want to search for a single id.

db.items.update({ '_id': ObjectId("55512b7070722d22d3050000") }, { $set: {'category_name': 'Test' } })

Above is the mongo version of the query. I found translating ruby code to mongo code is the hard part as there are a few pieces that can be a bit hard to find in the documentation.

http://www.rubydoc.info/gems/mongo/Mongo%2FCollection%3Aupdate_one