Mongodb ruby driver API(中文)

1. 開始
1.1 使用gem
經過kernel方法使用mongo gem
require 'rubygems'    #ruby1.9以上版本不須要
require 'mongo'
include Mongo模塊使得Mongo類一直可見而不用指定Mongo命名空間。
1.2 建立一個鏈接
一個MongoClient呈現一個MongoDB的鏈接
mongo_client = MongoClient.new("localhost", 27017)
這個驅動在每次寫操做後都會發送一個getlasterror命令來確保寫成功。1.8版本之前是沒有指定 ':safe => true'來實現寫保護的。
能夠選定mongodb的地址和端口號來鏈接實例:
mongo_client = MongoClient.new # (optional host/port args)
mongo_client = MongoClient.new("localhost")
mongo_client = MongoClient.new("localhost", 27017)
1.3 列出全部的數據庫
mongo_client.database_names     # lists all database names
mongo_client.database_info.each { |info| puts info.inspect }
database_info返回一個數據庫名和數據大小的哈希映射。

2. 使用數據庫
可使用Mongo::MongoClient實例來獲取Mongo::DB實例(返回數據庫名稱)。數據庫能夠不存在,若是不存在,Mongodb會建立它。
db = mongo_client.db("mydb")
db = MongoClient.new("localhost", 27017).db("mydb")
此時,db對象將會鏈接mongodb服務器指定數據庫,每一個數據庫實例使用服務器一個不一樣的套接字。
2.1 認證
mongodb能夠經過使用用戶名和密碼工做在一個安全模式。
當工做在這個模式下,客戶端須要提供一個用戶名和密碼完成鏈接,不然將會報錯。
2.2 使用一個集合
能夠鏈接一個集合經過collection方法:
coll = db.collection("testCollection")
這和[]方法同樣:
coll = db["testCollection"]
一旦獲取集合對象,就能夠在上面作create, read, update, and delete (CRUD) 等操做。
2.3 利用insert建立一個集合
一旦獲取collection對象,就能夠向集合建立或插入文檔,文檔格式是JSON格式的。
{
  "name" : "MongoDB",
  "type" : "database",
  "count" : 1,
  "info" : {
    x : 203,
    y : 102
  }
}
上面的文檔有內嵌數據,要實現這個,須要使用哈希或者有序哈希來完成。
doc = {"name" => "MongoDB", "type" => "database", "count" => 1, "info" => {"x" => 203, "y" => '102'}}
id = coll.insert(doc)
返回結果:
=> BSON::ObjectId('5358775858e53d20b0000001')
2.4 獲取集合列表
每一個數據有一個或多個集合。能夠獲取他們呢的列表。
db.collection_names
返回結果:
=> ["system.indexes", "testData3", "test"]
2.5 插入多個文檔
爲了示範更多有趣的查詢,須要向集合添加多個文檔,文檔格式以下:
{
    "i" : value
}
100.times { |i| coll.insert("i" => i) }
注意能夠向同一集合插入格式不一樣的文檔,這就是mongodb的模式自由概念。

3. 利用find和find_one讀取文檔
3.1 用find_one讀取集合中的一條文檔
獲取集合中的一條文檔記錄,適應findOne方法,這個方法返回一個文檔。
coll.find_one
返回結果:
=> {"_id"=>BSON::ObjectId('5358775858e53d20b0000001'), "name"=>"MongoDB", "type"=>"database", "count"=>1, "info"=>{"x"=>203, "y"=>"102"}}
 _id元素是mongodb自動添加的。
3.2 利用find方法從一個遊標讀取全部文檔
爲了獲取集合全部文檔,可使用find方法返回遊標對象,能夠容許迭代匹配到的結果文檔。
ruby驅動的遊標是可列舉的,可使用Enumerable#each,Enumerable#map等方法。例如:
coll.find.each { |row| puts row.inspect }
這樣能夠返回集合中的101條文檔,也可使用Enumerable#to_a。
puts coll.find.to_a
也可使用 #each_slice來獲取文檔塊以便成批處理。
# retrieve and process 10 documents at a time from cursor
coll.find.each_slice(10) do |slice|
  puts slice.inspect
end
提示:to_s方法能夠把全部結果寫入內存中,若是處理每一個文檔是無效的。爲了更加有效利用內存,使用each方法處理代碼塊來處理遊標。
3.3 指定查詢
可使用find一個哈希集合來查找知足條件的文檔。
coll.find("_id" => id).to_a
選定條件:
coll.find("i" => 71).to_a
返回結果:
=> [{"_id"=>BSON::ObjectId('5358786a58e53d20b0000049'), "i"=>71}]
3.4 排序集合中的文檔
排序文檔使用sort方法,這個方法能夠利用一個key或者[key, direction]對。
方向默認是升序的,由Mongo::ASCENDING,:ascending,或:asc指定,然而也可使用降序,由Mongo::DESCENDING,:descending,或:desc來指定。
# Sort in ascending order by :i
coll.find.sort(:i)

# Sort in descending order by :i
coll.find.sort(:i => :desc)
兩者都返回遊標對象。
3.5 集合文檔數目統計
可使用count方法
coll.count
=> 101
3.6 獲得一個查詢文檔的集合
若是查詢"i" > 50的文檔:
puts coll.find("i" => {"$gt" => 50}).to_a
若是查詢20 < "i" <= 30而且的文檔:
puts coll.find("i" => {"$gt" => 20, "$lte" => 30}).to_a
返回結果:
{"_id"=>BSON::ObjectId('5358786958e53d20b0000017'), "i"=>21}
{"_id"=>BSON::ObjectId('5358786958e53d20b0000018'), "i"=>22}
{"_id"=>BSON::ObjectId('5358786958e53d20b0000019'), "i"=>23}
{"_id"=>BSON::ObjectId('5358786958e53d20b000001a'), "i"=>24}
{"_id"=>BSON::ObjectId('5358786958e53d20b000001b'), "i"=>25}
{"_id"=>BSON::ObjectId('5358786958e53d20b000001c'), "i"=>26}
{"_id"=>BSON::ObjectId('5358786958e53d20b000001d'), "i"=>27}
{"_id"=>BSON::ObjectId('5358786958e53d20b000001e'), "i"=>28}
{"_id"=>BSON::ObjectId('5358786958e53d20b000001f'), "i"=>29}
{"_id"=>BSON::ObjectId('5358786958e53d20b0000020'), "i"=>30}
=> nil
3.7 返回查詢的映射域
使用:fields選項指定返回域。
puts coll.find({"_id" => id}, :fields => ["name", "type"]).to_a
puts coll.find({"_id" => "5358786958e53d20b0000017"}, :fields => ["i"]).to_a
3.8 使用正則表達式查詢
puts coll.find({"name" => /^M/}).to_a
也能夠動態的構建一個正在表達式:
params = {'search' => 'DB'}
search_string = params['search']

# Constructor syntax
puts coll.find({"name" => Regexp.new(search_string)}).to_a

# Literal syntax
puts coll.find({"name" => /#{search_string}/}).to_a
儘管mongodb不會受到SQL注入攻擊,可是也須要檢查惡意的字符串。

4. 更新文檔
可使用不少update方法更新文檔。
doc["name"] = "MongoDB Ruby"
coll.update({"_id" => id}, doc)
或者使用原子操做來改變一個單個值:
coll.update({"_id" => id}, {"$set" => {"name" => "MongoDB Ruby"}})
驗證更新:
puts coll.find("_id" => id).to_a

5. 刪除文檔
使用remove來刪除文檔。
coll.count
coll.remove("i" => 71)
coll.count
puts coll.find("i" => 71).to_a
上面的例子展現了總數減小,相關文檔查詢不到。
若是沒有參數,delete方法會刪除全部文檔:
coll.remove
coll.count
在程序中須要謹慎使用

6. 索引
6.1 建立索引
mongodb支持索引,爲了建立一個索引,你須要指定索引名稱和一組或一個域被索引:
# create_index assumes ascending order; see method docs
# for details
coll.create_index("i")
若是要指定複合索引或者縮減索引須要使用稍微複雜點的語法。索引指定必須是[filed name, direction]對。
方向應該指定爲Mongo::ASCENDING 或 Mongo::DESCENDING。
# Explicit "ascending"
coll.create_index([["i", Mongo::ASCENDING]]) # ruby 1.8
coll.create_index(:i => Mongo::ASCENDING) # ruby 1.9 and greater
使用遊標上的explain方法來展現mongodb如何經過索引查找數據。
coll.find("_id" => id).explain
coll.find("i" => 71).explain
coll.find("type" => "database").explain
上面的經過_id和i的查詢會使用比較快的BtreeCursor,type查詢會使用比較慢的BasicCursor。
6.2 獲取集合的索引列表
coll.index_information
6.3 建立和查詢地理信息索引
首先在一個擁有long-lat值的域上建立一個索引:
# ruby 1.8
people.create_index([["loc", Mongo::GEO2D]])

# ruby 1.9 and greater
people.create_index(:loc => Mongo::GEO2D)
獲取最接近座標50,50的20個位置:
people.find({"loc" => {"$near" => [50, 50]}}, {:limit => 20}).each do |p|
  puts p.inspect
end

7. Dropping
7.1 刪除索引
刪除一個次級索引使用drop_index方法:
coll.drop_index("i_1")
coll.index_information
已經刪除的索引不會列出來。
7.2 刪除全部索引
coll.drop_indexes
coll.index_information
只有主索引"_id"會保留。
7.2 刪除集合
coll.drop
db.collection_names
也可使用drop_collection方法代替:
db.drop_collection("testCollection")
7.3 刪除數據庫
在mongo客戶端使用drop_databases來刪除數據庫:
mongo_client.drop_database("mydb")
mongo_client.database_names

8. 數據庫管理
一個數據庫能夠有下面三個級別中一個profiling級別:
關閉(:off),慢查詢(:slow_only),全部查詢(:all)。查看級別:
puts db.profiling_level   # => off (the symbol :off printed as a string)
db.profiling_level = :slow_only
驗證數據庫會在一切正常或者由於問題而拋出異常產生一個有趣的哈希。
p db.validate_collection('coll_name')
相關文章
相關標籤/搜索