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)
- 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