一些 Mongoid 的心得
之前寫 http://touchlim.it 的時候用到了 MongoDB 和 Redis,其中 MongoDB 的部份交給了 Mongoid 去負責,以下就來寫我自己的使用想法。嚴格說來我不會 MongoDB,請大家鞭小力一點 Q____Q
Mongoid 最大的特色為,(抄一下官網說明 XDDD)具有類似 Active Record 的眾多 API(Relation、Validation),但仍保持 MongoDB 的眾多特性(不需要 Schema、Document-oriented、Atomic operations...)。跟 Rails 3 來說也算是十分契合 :)
Setup
安裝 MongoDB 和 Mongoid 其實是過程中最簡單的部份。 =3=
MongoDB 的話,Mac 上請愛用 homebrew,Ubuntu 的話可以偷懶用 10gen 提供的 apt source 去裝:
http://www.mongodb.org/display/DOCS/Ubuntu+and+Debian+packages
其他 Distro 就自己去看 MongoDB 的網頁。
安裝過後認真讀一下 MongoDB 的網頁,作一些基礎的設定和試玩。
Mongoid 的話,把 mongoid 和 bson_ext 加到 Gemfile 就好了。注意 bson_ext 1.4.x 是爛的,所以請 ~>1.3.1 或 ~> 1.5.1 Orz
Use Mongoid
基本上看官方網站就可以了:http://mongoid.org/
如果你踩到地雷,通常一定是因為你不習慣 Mongoid 或 Ruby Orz
我也只說一下我自己的個人心得:
* 使用 Mongoid 的 Model:include Mongoid::Document
,每一個欄位都是用 field
。不需要寫 Migration,因為 MongoDB 是沒有 Schema 的!(用起來超爽的啦 =3=)
* 由於 MongoDB 有,Mongoid 自然也有 Indexing。在 Model 裡寫好後跑 bundle exec rake db:mongoid:create_indexes
就好了。Indexing 請參考官方文件...... http://mongoid.org/docs/indexing.html
* Querying 上的不同:對 Mongoid 的 Model 下 .all
、.where
之類的東西,他只會先把所有條件 Chaining 起來之後編譯成 Criteria 物件,等到要實際進行資料存取的時候才會真的下 BSON 指令去執行。(BSON 是 MongoDB 裡 Query 的語言)
所以 Person.all
的時候他會跑給你一個 Mongoid::Criteria,如果你需要拿出所有 Person 裡的資料,你就需要實際去進行存取。其方法之一是 #entries( Enumerable 裡頭的東西),如 Person.all.entries
,這樣 Mongoid 就會去跑 BSON 指令後回傳結果,而使用 #each 也可以得到預期的結果:
@people = Person.all
@people.each do |person|
# 在 .each 作 Enumerate 的期間就會執行 BSON 指令,因此這裡拿到的東西就會是 Person 的 Document
puts person.name
end
* (我猜應該是為了好的 ActiveRecord 相容性,) .find()
和 .count()
還是例外,他們下了之後就會直接執行。
.find()
也是下了 ID 之後就會給出對應的 Document,只差在 MongoDB 有自己的一套 Object ID 而已。find()
可以接受 String 的 Input,如 History.find('4ed63d4526a39b0e8a000001')
。
* 因為以上的種種特質,所以把 Model 轉用 Mongoid 之後,Controller 上幾乎不會有什麼變動......
* Mongoid 也有 Relation ,主要分成「Embed」和「Reference」兩種,「Embed」就是對應到的 Model 存成原來 Document 的 Nested Document,「Reference」就是存成不同的 Document 後以 Object ID 進行 Mapping。詳情請參考官方文件。
* Mongoid 甚至也有 Callback 和 Validation,但是我沒用到 Orz
* 如果你需要 created_at 和 updated_at,include Mongoid::Timestamps
。
------
大概就這樣吧,希望大家能少踩一點地雷 Q___Q
謝謝哩~網路上一大堆mysql文章,其實RoR應該在NoSQL上可以有很大的發揮才是。像是Java要調用mongodb會很囉嗦的,請問哪邊可以RoR+mongodb的實例呢?
這個站就是 Rails + Mongodb ...
各位誰對 mongoid 裡面的 many to many 比較有經驗? 這裡介紹的兩種 many-to-many http://railscasts.com/episodes/47-two-many-to-many
第一種 has_and_belongs_to_many 在mongoid ok, 第二種要用到 :through, 我在 mongoid 找不到相對應的功能可下