1. 程式人生 > >mgo初步接觸

mgo初步接觸

Intro

mgomongodb的go語言繫結,第一次在靜態型別語言中使用ORM,故留個筆記。

模型

mongodbschema-less無模式的NoSQL非關係型資料庫,理論上來說,在同一個表(mongodb中稱為collection)中的行(mongodb稱為document)也可能具有不同的欄位。

簡單的模型可以如此定義。

type Article struct {
    Id      bson.ObjectId `bson:"_id,omitempty"`
    Title   string        `bson:"title"`
    Content string        `bson:"content"` 
}

使用了struct field tag,參考golang英文wiki,還有這裡的golang spec

其中Id這個欄位是使用mongodb自己生成的_id欄位,omitempty表示該欄位在序列化的時候只接受非零值(0,空slice,或者空map都算是零值),按照我的理解就是,如果Id0,那麼過了Marshal之後應該是見不到_id這個欄位的。

這個設計保證了不會誤存go語言給Id的預設值0,造成鍵衝突。

bson:"<field_name>"json:"<field_name>"類似,聲明瞭序列化後欄位的鍵名。

回到正題,簡單欄位如int32

float32string都不需要特殊處理,時間可能是一個需要關注的地方。

type Article struct {
    Id        bson.ObjectId `bson:"_id,omitempty"`
    CreatedAt time.Time     `bson:"created_at"`
    UpdatedAt time.Time     `bson:"updated_at"`
    Title     string        `bson:"title"`
    Content   string        `bson:"content"` 
}

注意的一個點是bson.MongoTimestamp在我使用時出現了無法正確反序列化mongodb查詢結果的問題,原因不明。資料是手動在mongo shell裡插入的,使用new Date()賦值了created_atupdated_at。有人知道怎麼回事的話請告訴我。

使用time.Time就可以正常序列化了。

查詢

mgo查詢基本思路是:建立連線(mgo.Dial)、選擇資料庫(Session.DB)、選擇集合(Database.C)、設定條件(Collection.Find)、取出結果(Query.All)。

簡單例子如下。

func findSomething() {
    sess, err := mgo.Dial("mongodb://localhost:27017")
    if err != nil {
        panic(err)
    }
    
    var result []Article
    sess.DB("test").C("articles").Find(bson.M{"title": "mgo初接觸"}).All(&result)
    fmt.Println(result)
}

和一般mongo查詢一樣支援一些排序之類的操作。

Query.Sort按照文件說法可以寫出這樣的查詢:Find(bson.M{}).Sort("-created_at")-號表示降序。

Query.skip可以跳過一定數量的結果,Query.One表示只取一個元素,Query.Limit限制查詢結果的數量等等...

寫入

寫入的基本操作是Collection.InsertCollection.Update以及兩個變體Collection.UpdateId以及Collection.UpdateAll

最基本的Collection.Insert應該不用多解釋。

Collection.Update按照文件描述,是查詢到匹配引數selector條件的一個document並更新。通常我們更新document應該是用_id欄位來唯一確定,顧名思義Collection.UpdateId就是這樣一個便捷方法。

更新多個document的時候就用到了Collection.UpdateAll了。引數和Collection.Update無異,selector確定要更新的document有哪些,update引數則確定要更新到什麼樣子。