mongodb驅動接口


mongodb對外接口或驅動:https://docs.mongodb.com/ecosystem/drivers/,包含C,C++,Go,Python等。

C驅動

mongodb的C驅動,即libmongoc,是一個用於開發mongodb的C庫。依賴libbson,libbson用於生成和解析BSON documents。

mongoDB C Driver官網:http://mongoc.org/libmongoc/current/index.html

安裝

下載最新的1.14.1tar包安裝(mongo-c-driver-1.14.1.tar.gz)。

sudo apt-get install cmake libssl-dev libsasl2-dev

$ wget https://github.com/mongodb/mongo-c-driver/releases/download/x.y.z/mongo-c-driver-x.y.z.tar.gz
$ tar xzf mongo-c-driver-x.y.z.tar.gz
$ cd mongo-c-driver-x.y.z
$ mkdir cmake-build
$ cd cmake-build
$ cmake -DENABLE_AUTOMATIC_INIT_AND_CLEANUP=OFF ..
$ make
$ sudo make install
$ sudo make uninstall

編譯鏈接

gcc -o hello_mongoc hello_mongoc.c $(pkg-config --libs --cflags libmongoc-1.0)
gcc -o hello_mongoc hello_mongoc.c $(pkg-config --libs --cflags libmongoc-static-1.0)
$ gcc -o hello_mongoc hello_mongoc.c \
    -I/usr/local/include/libbson-1.0 -I/usr/local/include/libmongoc-1.0 \
    -lmongoc-1.0 -lbson-1.0
$ ./hello_mongoc

增刪改查

參考:Basic CRUD Operations

Go驅動

mongodb的Go驅動很多,官方提供的驅動:https://godoc.org/go.mongodb.org/mongo-driver/mongo 或 https://docs.mongodb.com/ecosystem/drivers/go/

edgex中用到的是mgo(社區版):https://github.com/globalsign/mgohttps://godoc.org/github.com/globalsign/mgo。其clone於gopkg.in/mgo.v2(不再更新)。

mgo的核心基於session,Dail()基於url建立連接用於后續的查詢:

session, err := mgo.Dial(url)
c := session.DB(database).C(collection)
err := c.Find(query).One(&result)

函數原型:

func (c *Collection) Find(query interface{}) *Query

Find prepares a query using the provided document. The document may be a map or a struct value capable of being marshalled with bson.

The map may be a generic one using interface{} for its key and/or values, such as bson.M, or it may be a properly typed map.

Providing nil as the document is equivalent to providing an empty document such as bson.M{}.

func (q *Query) One(result interface{}) (err error)

One executes the query and unmarshals the first obtained document into the result argument.

The result must be a struct or map value capable of being unmarshalled into by gobson.

This function blocks until either a result is available or an error happens. For example:

err := collection.Find(bson.M{"a": 1}).One(&result)

查詢語句語法參考:https://docs.mongodb.com/manual/tutorial/query-documents/

package main

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

type Person struct {
    Name string
    Phone string
}

func main() {
    session, err := mgo.Dial("127.0.0.1")
    if err != nil {
        panic(err)
    }
    defer session.Close()

    session.SetMode(mgo.Monotonic, true)

    c := session.DB("test").C("people")
    err = c.Insert(&Person{"Ale", "+55 53 8116 9639"},
        &Person{"Cla", "+55 53 8402 8510"})
    if err != nil {
        panic(err)
    }

    result := Person{}
    err = c.Find(bson.M{"name": "Ale"}).One(&result)
    if err != nil {
        panic(err)
    }

    fmt.Println("Phone:", result.Phone)
}

mgo中session

Strong
session 的讀寫一直向主服務器發起並使用一個唯一的連接,因此所有的讀寫操作完全的一致。
Monotonic
session 的讀操作開始是向其他服務器發起(且通過一個唯一的連接),只要出現了一次寫操作,session 的連接就會切換至主服務器。

由此可見此模式下,能夠分散一些讀操作到其他服務器,但是讀操作不一定能夠獲得最新的數據。
Eventual
session 的讀操作會向任意的其他服務器發起,多次讀操作並不一定使用相同的連接,也就是讀操作不一定有序。session 的寫操作總是向主服務器發起,但是可能使用不同的連接,也就是寫操作也不一定有序。

mgo中全局session有兩個問題:

1)效率問題。全局session只有一個socket,不支持並發。

2)mgo.Session緩存的一主一從連接,實例本身不負責維護,需要應用維護。也就是說,slaveSocket,masterSocket任意其一,連接斷開,Session自己不會重置緩存,該Session的使用者如果不主動重置緩存,調用者得到的將永遠是EOF這種情況在主從切換時就會發生,在網絡抖動時也會發生。這是致命的,連接斷開或MongoDB重啟時永遠連接不上,報EOF。

解決全局session問題的方法有兩個,采用SessionCopy機制或Eventual模式。Copy機制時,每次查詢都用一個session,查詢完后關閉session,讓mgo維護session復用。

參考:

https://cardinfolink.github.io/2017/05/17/mgo-session/  mgo的session與連接池

https://www.bbsmax.com/A/rV574pAXdP/ golang mgo的mongo連接池設置:必須手動加上maxPoolSize

mgo中日志實現

    // 實現 mongo.Logger 的接口
    type MongoLog struct {
    }
    
    func (MongoLog)Output(calldepth int, s string) error {
        log.SetFlags(log.Lshortfile)
        return log.Output(calldepth,s)
    }
    mgo.SetDebug(true)  // 設置DEBUG模式
    mgo.SetLogger(new(MongoLog)) // 設置日志. 

func ConfigCollection() *mgo.Collection {
  if configCollection != nil {
    return configCollection
  }
  db := dbConfig()
  url := db.Host + ":" + strconv.Itoa(db.Port)
  log.Printf("mongo connect info(url:%s, dbName:%s, collection:%s)\n", url, db.DB, db.Collection)
  session, err := mgo.Dial(url)
  if err != nil {
    log.Fatalf("Connect mongo failed: %v \n", err)
  }
  // session.SetMode(mgo.Monotonic, true
  // mgo.SetDebug(true)
  // mgo.SetLogger(new(mongoLog))
  session.SetMode(mgo.Eventual, true)
  session.SetSocketTimeout(2 * time.Second)
  session.SetSyncTimeout(2 * time.Second)

 
         

  configCollection = session.DB(db.DB).C(db.Collection)
  return configCollection
}

要使日志使能,必須SetLogger()。

 

參考:

  1. Go Web編程 5.6 NOSQL數據庫操作
  2. http://labix.org/mgo
  3. http://labix.org/gobson
  4. https://gopkg.in/mgo.v2 可參考文檔
  5. https://godoc.org/github.com/globalsign/mgo#Session.SetMode


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM