This client is under development. You can try
- em-mongo with Eventmachine inside
- Official mongo-ruby-driver from 10gen
- Moped from Mongoid guys
Monga
Yet another MongoDB Ruby Client.
It supports three kind of interfaces:
- Asynchronous over EventMachine
- Synchronous (on Fibers)
- Blocking (over TCPSocket, kgio actually)
Introduction
Asynchronous API will be familiar to Node.js developers. Instead of Deferrable Object you will receive err, response
into callback.
EM.run do
client = Monga::Client.new(type: :em)
db = client["testDb"]
collection = db["testCollection"]
# Fire and forget
collection.insert(artist: "Madonna", title: "Frozen")
# Safe method
collection.safe_insert(artist: "Madonna", title: "Burning Up") do |err, response|
if err
puts "Ha, an error! #{err.}"
else
puts "Job is done. Let's do more job"
# Cursor
collection.find.batch_size(100).limit(500).each_doc do |err, doc, iter|
if iter
puts "What have we got here: #{doc['title']}"
iter.next
else
puts "No more documents in collection"
EM.stop
end
end
# Yes, you should call `iter.next`, welcome to callback world!
end
end
end
Synchronous mode is more simple. It is just like blocking mode, but you can use pool of fibers to make it as fast as lightning.
EM.synchrony do
client = Monga::Client.new(type: :sync)
db = client["testDb"]
collection = db["testCollection"]
# Fire and forget
collection.insert(artist: "Madonna", title: "Frozen")
# Safe method
collection.safe_insert(artist: "Madonna", title: "Burning Up")
puts "Job is done"
# Cursor
docs = []
collection.find.batch_size(100).limit(500).each_doc do |doc|
puts "What have we got here: #{doc['title']}"
docs << doc
end
puts "We have got #{docs.size} documents in this pretty array"
EM.stop
end
Blocking mode is as simple as a potato
# client = Monga::Client.new(type: :block)
client = Monga::Client.new
db = client["testDb"]
collection = db["testCollection"]
# Fire and forget
collection.insert(artist: "Madonna", title: "Frozen")
# Safe method
collection.safe_insert(artist: "Madonna", title: "Burning Up")
puts "Job is done"
# Cursor
docs = []
collection.find.batch_size(100).limit(500).each_doc do |doc|
puts "What have we got here: #{doc['title']}"
docs << doc
end
puts "We have got #{docs.size} documents in this pretty array"
To Do List
- [ ] Write a Wiki
- [ ] Write comments
- [ ] Grammar improvement ;)
Clients
- [x] Client (Single instance connection)
- [x] ReplicaSetClient
- [ ] MasterSlaveClient
- [x] ReadPref
- [ ] Sharding Support
Connection
- [x] Connection
- [x] Autoreconnect
- [x] Connection Pool
Protocol
- [x] OP_QUERY
- [x] OP_GET_MORE
- [x] OP_KILL_CURSORS
- [x] OP_INSERT
- [x] OP_UPDATE
- [x] OP_DELETE
- [x] OP_REPLY
Database
- [x] create_collection
- [x] drop_collection
- [x] get_last_error
- [x] drop_indexes
- [x] get_indexes
- Authentication
- [ ] login
- [ ] logout
- [ ] add_user
- [ ] check maxBsonSize / validate
- [x] cmd
- [x] eval
- [x] aggregate
- [x] distinct
- [x] group
- [x] mapReduce
- [x] text
- [ ] gridfs?
Collection
- QUERY_OP
- [x] find
- [x] find_one (first)
- [x] sorting
- INSERT_OP
- [x] insert (single)
- [x] insert (batch)
- [x] safe_insert
- FLAGS
- [x] continue_on_error
- UPDATE_OP
- [x] update
- [x] safe_update
- FLAGS
- [x] upsert
- [x] multi_update
- DELETE_OP
- [x] delete
- [x] safe_delete
- FLAGS
- [x] single_remove
- INDEXES
- [x] ensure_index
- [x] drop_index
- [x] drop_indexes
- [x] get_indexes
- [x] count
- [x] all
- [x] cursor
- [ ] DBRef
Cursor
- [x] limit
- [x] skip
- [x] batch_size
- [x] get_more
- [x] next_document
- [x] next_batch
- [x] each_doc
- [x] kill
- [x] mark_to_kill
- [x] batch_kill
- [x] explain
- [x] hint
- Flags
- [x] tailable_cursor
- [x] slave_ok
- [x] no_cursor_timeout
- [x] await_data
- [x] exhaust
- [x] partial
ISSUES handled with
Some commands, such as db.getLastError
, db.count
and other db.commands
requires numberToReturn
in OP_QUERY to be setted as -1
. Also this commands should return a response. If nothing returned it should be interpreted as an Exception. Also, in contrast to the other queries it could return errmsg
which should be interpreted as an Exception too. Other query methods could return err
response.
To create index you can't call any db.ensureIndex
command but you should insert a document into sytem.indexes
collection manually. To get list of indexes you should fetch all documents from this collection. But to drop index you should call specific db.dropIndexes
command.
multi_update
flag works only with $
commands (i.e. $set: { title: "blahblah" }
)