1. 程式人生 > >Mongodb Api for ruby

Mongodb Api for ruby

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