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?
-
running on mongoid 3 or 2 if 2 it different adapater than moped cant remember the name but I guess it `mongodb-ruby-driver` – Viren Feb 13 '13 at 07:39
-
yes, I'm using mongoid 3 – Andrew Feb 13 '13 at 16:36
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

- 227,796
- 193
- 515
- 708
-
Hi Andrew, your answer is useful, but I'm using mongoid and direct access to collections as mentioned in your answer, it works fine but some how after using this mongoid activerecord operations like Model.save, Model.update_attributes,etc. are not working, Can you please suggest some solution(s) for this? – Niral Munjariya Oct 29 '14 at 09:55
-
Hard to know what's going on without seeing some code samples. I think you should post this as your own question and include a code sample. – Andrew Oct 29 '14 at 15:28
-
Thanks for the reply Andrew, but I found the cause and resolved the same. – Niral Munjariya Oct 30 '14 at 05:40
-
I think it's important to mention that if the file is an script like test.rb , you have to set ` require 'mongoid' ` – Machinerium Oct 14 '15 at 03:06
-
NOTE: The clients will show only when you are connected to a database. Otherwise it will say `NameError: uninitialized constant Mongoid::Sessions` – poorva Jan 12 '17 at 10:51
-
`Mongoid::Sessions.default` doesn't work anymore, now it is: `Mongoid::Clients.default` – Bengineer Jul 22 '20 at 21:00
For Mongoid 5:
db = Mongoid::Clients.default
collection = db[:collection_name]
Now we can perform queries on the collection

- 226,338
- 43
- 373
- 367

- 201
- 2
- 4
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

- 5,812
- 6
- 45
- 98
-
The one that is being marked as answer only works in `rails console`, but this one, works inside the `Model`. I'm using Mongoid 4.0.2. – Charlie Mar 20 '15 at 10:37
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.

- 121
- 3
-
That's what I thought, but how can I access it? In the docs the examples show `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. – Andrew Feb 11 '13 at 21:30
-
3You should be able to get it from Mongoid: `Mongoid::Sessions.default` will return a `Moped::Session` from which you can do all the Moped stuff. – Ben Ashford Feb 11 '13 at 22:54
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}"

- 532
- 1
- 5
- 25

- 199
- 1
- 11
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

- 226,338
- 43
- 373
- 367

- 3,250
- 3
- 24
- 22