Sử dụng mongo DB với Golang

March 15, 2019
mongo DB Golang

Cũng như rất nhiều các ngôn ngữ server side khác. Go cũng có thể kết hợp với rất nhiều cơ sở dữ liệu khác nhau. Hầu hết các database mới nhất hiện nay đều được hỗ trợ rất đầy đủ và dễ sử dụng. Bên cạnh đó rất nhiều các developer đã viết thêm ORM để đơn giản hóa các câu truy vấn sql. Ở bài viết này mình sẽ hướng dẫn tích hợp mongo DB vào trong project với golang và thao tác với chúng.

Giới thiệu package

https://github.com/go-mgo/mgo/tree/v2

Đây là package mình thường hay sử dụng để tương tác golang với mongo. pkg này khá đơn giản, tài liệu + example tương đối đầy đủ. Hơn thế nữa nó còn được khá nhiều các developer đánh giá rất cao. Đây là home page của nó. https://gopkg.in/mgo.v2. Còn đây là full documents tương đối đầy đủ https://godoc.org/gopkg.in/mgo.v2

Tích hợp và sử dụng thôi.

Đầu tiên cũng như mọi pkg khác với golang bạn có rất nhiều các để tích hợp dependency về

ví dụ + https://github.com/golang/dep + https://glide.sh/ + …

Tuy nhiên để sử dụng nhanh mình sẽ dùng như trong docs của mongo.

$ go get gopkg.in/mgo.v2

Trong file main.go sẽ import

import "gopkg.in/mgo.v2"

Sau khi bạn đã import xong mongo về project. Hãy tạo ra file config để đảm bảo có thể thay đổi các tham số 1 cách dễ dàng.

config.go

package config


type config struct {
    MongoDBHost string
    MongoDBUser string
    MongoDBPwd  string
    Database    string
}

var (
    AppConfig config
)

func Init() {
    AppConfig = config{
        MongoDBHost: localhost:27017,
        MongoDBUser: ""
        MongoDBPwd: ""
        Database: "demo"
    }
}

Sau khi đã có file config việc cần làm tiếp theo là bạn phải tạo 1 session để mỗi phiên truy cập sẽ thao tác vào db qua session này.

Mình sẽ tạo ra 1 file database.go như sau

package config

import (
    "fmt"
    "log"
    "time"

    mgo "gopkg.in/mgo.v2"
)

type Session struct {
    session *mgo.Session
}

func NewSession() *Session {
    session, err := mgo.DialWithInfo(&mgo.DialInfo{
        Addrs:    []string{AppConfig.MongoDBHost},
        Username: AppConfig.MongoDBUser,
        Password: MongoDBPwd,
        Timeout:  60 * time.Second,,
    })

    if err != nil {
        log.Fatalf("[ConnectDB]: %s\n", err)
    }
    session.SetMode(mgo.Monotonic, true)

    return &Session{session}
}

func (s *Session) Copy() *mgo.Session {
    return s.session.Copy()
}

func (s *Session) Close() {
    if s.session != nil {
        s.session.Close()
    }
}

Vậy là đã xong các file tích hợp mongo db với golang. Phần tiếp theo chúng ta sẽ sử dụng và query.

Sử dụng

Sau khi config session hoàn tất. Có rất nhiều design pattern để các bạn implement file connect db vào. Ở bài viết này mình sẽ implement trực tiếp vào trong file main cho dễ sử dụng. file main.go của mình như sau.

package main

import (
    "..../config"
    "gopkg.in/mgo.v2/bson"
    "time"
    "log"
    "fmt"
)

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

func main() {
    config.Init()
    s := config.NewSession()
    defer s.Close()

    c := s.Copy().DB(config.AppConfig.Database).C("blogs")
    // Get All Blog
    blogs := []blog{}
    c.Find(nil).All(&blogs)

    // Out put
    fmt.Println(blogs)

}

Để lấy tất cả các bản ghi trong db bạn có thể sử dụng Find(nil) Tức là không kèm điều kiện và fill tất cả data vào 1 array struct blog

Để tìm chính xác giá trị dựa vào id các bạn có thể thay đổi câu truy vấn như sau

....

func main() {
....

    id := "id hex..."
// Find Blog by id
    blog := blog{}
    c.Find(bson.M{"_id": bson.ObjectIdHex(id)}).One(&blog)

}

// Out put
    fmt.Println(blog)

Để insert bản ghi vào db cũng không có gì phức tạp cả các bạn có thể thao tác như sau


func main() {
....

    blog := blog{
        Id: bson.NewObjectId(),
        Name: "New blog",
        Content: "New Content",
        CreatedAt: time.Now(),
        UpdatedAt: time.Now(),
    }
    err := c.Insert(&blog)
    if err != nil {
        log.Fatalf("[InsertDB]: %s\n", err)
    }
}

Kết luận

Bài viết trên đã hướng dẫn các bạn thao tác lấy data và insert vào mongo db. Để hiểu sâu và truy vấn nhiều hơn tìm hiểu thêm và tài liệu https://godoc.org/gopkg.in/mgo.v2 này. Mongo là 1 dạng Nosql, nên truy vấn của nó tương đổi nhanh. Bạn có thể thao tác lượng dữ liệu lớn kết hợp cũng go thì nó sẽ truy xuất nhanh hơn bao giờ hết. Cám ơn các bạn đã đọc bài viết này. Hi vọng nó mang lại 1 phần nào kiến thức cho các bạn.