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>"類似,聲明瞭序列化後字段的鍵名。

回到正題,簡單字段如int32float32string都不需要特殊處理,時間可能是一個需要關注的地方。

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參數則確定要更新到什麼樣子。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章