這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
mgo庫是一個很好用的MongoDB
驅動。對我們來說,主力資料庫是MongoDB
,因此這個驅動對我們來說也是非常重要的。但是,mgo庫有些問題算是一些坑,這裡我做了一些簡單的整理。
一些關於bson.ObjectId的問題
ObjectId為空白的判斷
如果你看bson.ObjectId
定義的話,它是一個string
類型的資料。但是如果你直接定義一個結構,並且產生對象時,這個對象並不是這樣的。
我們首先定義一個結構體:
type Home struct { ID bson.ObjectId `bson:"_id,omitempty"` Name string `bson:"name"`}
然後看看一個產生的內容
h := Home{Name: "123"}fmt.Println(h.ID)
結果是ObjectIdHex("")
。換句話說,如果你是想判斷一個結構體的ObjectId
是否為空白,使用h.ID == ""
是一定會結果為false
的。如果你想判斷是否為空白,正確的方式應該為:
h := Home{Name: "123"}fmt.Println(h.ID)fmt.Println(h.ID.Hex() == "")
正確的產生ObjectId
首先值得注意的是NewObjectIdWithTime(t time.Time)
這個方法產生的ObjectId
並不是唯一的,結果可能導致的是插入失敗。最有效方式是設定ObjectId
對象支援omitempty
屬性,就像我上面產生的結構體一樣,由資料庫統一調配產生ObjectId。如果真的確實需要,可以選擇NewObjctId()
。
時間問題
之前看到有人問,為什麼儲存的時間進入到資料庫中慢了8個小時呢?原因是在儲存進入MongoDB
時,資料是按照UTC
時間(不懂什麼是UTC?看這裡)進行的儲存,但是取出是按照當前時區來取出。那麼問題來了,我的客戶如果不都是國人,我怎麼儲存時間呢?目前我們採用了兩種方式來確定資料庫的儲存時間。一種是Unix時間戳記
,這個是不受到時區的影響的,由前端格式化為對應的時區時間;另外一種則是需要在額外的對從MongoDB
資料庫中取出的資料進行額外的時區校準,簡單來說可以這樣:
type Home struct { ID bson.ObjectId `bson:"_id,omitempty"` Name string `bson:"name"` InsertTime time.Time `bson:"insert_time"`}func main() { sess, _ := mgo.Dial("127.0.0.1") c := sess.DB("test").C("home") h := Home{Name: "123", InsertTime: time.Now()} c.Upsert(bson.M{"name": "123"}, h) c.Find(bson.M{"name": "123"}).One(&h) fmt.Println(h.InsertTime.Format("2006-01-02 15:04:05")) tz, _ := time.LoadLocation("America/New_York") fmt.Println(h.InsertTime.In(tz).Format("2006-01-02 15:04:05"))}
更高效的使用Session
在MongoDB
中合理使用Session
可以更高效的操作資料庫,做法是在之前進行一次Copy
操作:
sessionCopy := mongoSession.Copy()defer sessionCopy.Close()collection := sessionCopy.DB(TestDatabase).C("buoy_stations")log.Printf("RunQuery : %d : Executing\n", query)// Retrieve the list of stations.var buoyStations []BuoyStationerr := collection.Find(nil).All(&buoyStations)if err != nil { log.Printf("RunQuery : ERROR : %s\n", err) return}log.Printf("RunQuery : %d : Count[%d]\n", query, len(buoyStations))
另外值得一提的是MongoDB本身,目前我們已經提升到了MongoDB 3.0+
版本,優勢是相對之前版本的WiredTiger
引擎比較令人印象深刻(如果有條件可以選擇最新的3.2版本)。大家對之前MongoDB
中索引建立的痛苦有印象,這個現象在WiredTiger
引擎中也有所改進。更多的改進可以在WiredTiger
的官網和MongoDB的效能白皮書中瞭解更多。最後,當然,我仍然不建議在非嚴重必要情況下建立多餘索引,這對MongoDB
的效能和資源消耗都有較大影響。
Golang