在 Ruby Rack 应用中直接使用 MongoDB Ruby Driver
-
在 Ruby 程序中使用 MongoDB 你有两种主要的选择:Mongoid 或者是 MongoDB 官方 的Ruby Driver。
有这么一种常见的说法:Mongoid 一般用于 Rack 应用程序,如 Rails,而 MongoDB Ruby Driver 则用在 Rack 应用以外的领域。
这主要是因为 Mongoid 作为 ActiveRecord 在 NoSQL 数据库上的替代品具有同 ActiveRecord 相似的API风格,对于熟悉后者的用户来说容易上手。
然而,在 Rack 应用程序中直接使用 MongoDB Ruby Driver 也并没有什么问题,与 Mongoid 相比还有一些优点:
- 简单 — 用一套 API 实现所有功能。相比之下,Mongoid 并未实现 MongoDB 的所有功能:当你需要做 aggregation 查询时,你不得不直接操作其底层 Driver API 来完成。也就是说,Mongoid 的用户与 MongoDB 打交道实际上需要两套 API:高级的 ODM 和低级的驱动。
- API 一致性 — 除了 Ruby,你很可能还要用到其他语言实现的 MongoDB Driver,如 JavaScript——Mongo Shell 的操作语言。这些官方实现的不同语言的 API 都有相似的风格,熟悉了其中一种就比较容易掌握另一种。
但是,直接在 Rack 里使用 MongoDB Ruby Driver 毕竟有一些不够方便的地方。下文将通过比较二者的典型用法来说明问题,并给出解决方案。
我们先来看一个 Mongoid 的例子:
require 'mongoid' class User include Mongoid::Document # ... end User.create(...) # Insert one document User.where(...) # Find documents
与 ActiveRecord 类似,首先你要定义一个 model 类,如
User
,其后的 CRUD 就跟 ActiveRecord 差不多。Mongoid 会自动连接数据库,根据用户定义的配置文件(缺省位于 your-app/config/mongoid.yml),如:
test: clients: default: database: testdb hosts: - localhost:27017
如果用 MongoDB Ruby Driver,你得这么做:
require 'mongo' # Firstly, make a connection to a database client = Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'testdb') # Secondly, get an object of Mongo::Collection collection = client[:users] # Then do whatever you want with the collection collection.insert_one(...) # Insert one document collection.find(...) # Find documents # ...
首先你需要建立一个连接 — 得到一个
client
对象,然后从它得到一个collection
对象,然后才能开始在其中插入或者查找文档。与 Mongoid 相比,这显得不那么方便:Mongoid 可以让你直接从 collection 对象 —
User
类 — 开始工作,也不需要你手工建立数据库连接;此外,有了 model 类定义,如
User
,就可以把相关的操作数据库的方法都定义在这个类中,像 ActiveRecord 那样,如:class User include Mongoid::Document # ... def change_password(old_pw, new_pw) end end
其实,解决这些问题一点也不难,只要给 MongoDB Ruby Driver 增加几个功能:
- model 类定义,像上面Mongoid的
class User; ... end
,并且用户可以直接把它当作 collection 对象来用 - 根据用户定义的配置文件自动连接数据库
mongo-document 这个 Gem 正是为此目的:
本帖下載内容已隐藏,请登入以查看隐藏内容!它的用法如下:
安装
gem install mongo-document
用例
require "mongo" require "mongo/document" class User include Mongo::Document # ... end # Here User can be used as if a collection object User.insert_one(...) # Insert one document User.find(...) # Find documents
这个
User
类含有Mongo::Collection
类型的对象的全部方法,包括insert_one
和find
等等 — 实际上,User
的内部实现含有一个 collection 对象(可以通过User.collection
得到);User 自身只有很少的几个方法,它把此外的方法调用都转发到它的 collection 对象上。mongo-document 会自动读取用户配置文件(缺省位于 your-app/config/database.yml),如:
test: hosts: - localhost:27017 database: testdb
Mongo::Client::new 方法的所有 options 都可以在这个配置文件中指定。
mongo-document 自身不到 100 行代码,十分轻巧,是 MongoDB Ruby Driver 在 Rack 应用中的好帮手。