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?
7 Answers
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
6 Comments
NameError: uninitialized constant Mongoid::SessionsHere 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
1 Comment
rails console, but this one, works inside the Model. I'm using Mongoid 4.0.2.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.
2 Comments
Moped::Session.new(host).use(database) but this information is already defined in a configuration file that Mongoid loads automatically. I should be able to access some sort of Moped object from Mongoid. I just don't know how.Mongoid::Sessions.default will return a Moped::Session from which you can do all the Moped stuff.Like anyone has mentioned here, your answer is Moped. Here is my example for a ruby script (simple file test.rb)
- Define a mongoid.yml (in this case, at localhost)
development:
sessions:
default:
database: test_development
hosts:
- localhost:27017
options:
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}"
Comments
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
mongodb-ruby-driver