Go实战--golang中使用MongoDB(mgo)
生命不止,继续 go go go !!! 昨天分享了golang如何操作redis数据库,那今天就介绍一下golang中如何使用mongodb数据库。 何为MongoDB?简介 MongoDB (from humongous) is a free and open-source cross-platform document-oriented database program. Classified as a NoSQL database program,MongoDB uses JSON-like documents with schemas. MongoDB is developed by MongoDB Inc. and is free and open-source,published under a combination of the GNU Affero General Public License and the Apache License. 特点 你可以在MongoDB记录中设置任何属性的索引 (如:FirstName=”Sameer”,Address=”8 Gandhi Road”)来实现更快的排序。 你可以通过本地或者网络创建数据镜像,这使得MongoDB有更强的扩展性。 如果负载的增加(需要更多的存储空间和更强的处理能力) ,它可以分布在计算机网络中的其他节点上这就是所谓的分片。 Mongo支持丰富的查询表达式。查询指令使用JSON形式的标记,可轻易查询文档中内嵌的对象及数组。 MongoDb 使用update()命令可以实现替换完成的文档(数据)或者一些指定的数据字段 。 Mongodb中的Map/reduce主要是用来对数据进行批量处理和聚合操作。 Map和Reduce。Map函数调用emit(key,value)遍历集合中所有的记录,将key与value传给Reduce函数进行处理。 Map函数和Reduce函数是使用Javascript编写的,并可以通过db.runCommand或mapreduce命令来执行MapReduce操作。 GridFS是MongoDB中的一个内置功能,可以用于存放大量小文件。 MongoDB允许在服务端执行脚本,可以用Javascript编写某个函数,直接在服务端执行,也可以把函数的定义存储在服务端,下次直接调用即可。 MongoDB支持各种编程语言:RUBY,PYTHON,JAVA,C++,PHP,C#等多种语言。 MongoDB安装简单。 MongoDB与redis的对比 MongoDB建议集群部署,更多的考虑到集群方案,Redis更偏重于进程顺序写入,虽然支持集群,也仅限于主-从模式。 When to use Redis? Caching If you have enough time to think about your DB design. If you need really high performance. If you don’t care that much about scaling. When to use MongoDB Prototyping,Startups,Hackathons When you need to change your schema quickly. Windows下安装MongoDB官网: 把安装位置加入到环境变量中,例如: 命令行键入: C:Userswangs>mongo.exe --version
MongoDB shell version v3.4.6
git version: c55eb86ef46ee7aede3b1e2a5d184a7df4bfb5b5
OpenSSL version: OpenSSL 1.0.1u-fips 22 Sep 2016
allocator: tcmalloc
modules: none
build environment:
distmod: 2008plus-ssl
distarch: x86_64
target_arch: x86_64
启动mongodb服务 命令行键入: C:Userswangs>mongod.exe --dbpath d:mongodb_datadb 2017-07-13T20:10:37.851-0700 I CONTROL [initandlisten] MongoDB starting : pid=5524 port=27017 dbpath=d:mongodb_datadb 64-bit host=LAPTOP-MNU6522J 2017-07-13T20:10:37.851-0700 I CONTROL [initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2 2017-07-13T20:10:37.852-0700 I CONTROL [initandlisten] db version v3.4.6 2017-07-13T20:10:37.853-0700 I CONTROL [initandlisten] git version: c55eb86ef46ee7aede3b1e2a5d184a7df4bfb5b5 2017-07-13T20:10:37.853-0700 I CONTROL [initandlisten] OpenSSL version: OpenSSL 1.0.1u-fips 22 Sep 2016 2017-07-13T20:10:37.853-0700 I CONTROL [initandlisten] allocator: tcmalloc 2017-07-13T20:10:37.853-0700 I CONTROL [initandlisten] modules: none 2017-07-13T20:10:37.853-0700 I CONTROL [initandlisten] build environment: 2017-07-13T20:10:37.853-0700 I CONTROL [initandlisten] distmod: 2008plus-ssl 2017-07-13T20:10:37.853-0700 I CONTROL [initandlisten] distarch: x86_64 2017-07-13T20:10:37.853-0700 I CONTROL [initandlisten] target_arch: x86_64 2017-07-13T20:10:37.853-0700 I CONTROL [initandlisten] options: { storage: { dbPath: "d:mongodb_datadb" } } 2017-07-13T20:10:37.948-0700 I STORAGE [initandlisten] wiredtiger_open config: create,cache_size=3540M,session_max=20000,eviction=(threads_min=4,threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics_log=(wait=0), 2017-07-13T20:10:38.768-0700 I CONTROL [initandlisten] 2017-07-13T20:10:38.768-0700 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2017-07-13T20:10:38.770-0700 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2017-07-13T20:10:38.772-0700 I CONTROL [initandlisten] 2017-07-14T11:10:39.846+0800 I FTDC [initandlisten] Initializing full-time diagnostic data capture with directory 'd:/mongodb_data/db/diagnostic.data' 2017-07-14T11:10:40.094+0800 I INDEX [initandlisten] build index on: admin.system.version properties: { v: 2,key: { version: 1 },name: "incompatible_with_version_32",ns: "admin.system.version" } 2017-07-14T11:10:40.094+0800 I INDEX [initandlisten] building index using bulk method; build may temporarily use up to 500 megabytes of RAM 2017-07-14T11:10:40.219+0800 I INDEX [initandlisten] build index done. scanned 0 total records. 0 secs 2017-07-14T11:10:40.221+0800 I COMMAND [initandlisten] setting featureCompatibilityVersion to 3.4 2017-07-14T11:10:40.282+0800 I NETWORK [thread1] waiting for connections on port 27017
客户端连接mongodb C:Userswangs>mongo.exe
MongoDB shell version v3.4.6
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.4.6
Welcome to the MongoDB shell.
For interactive help,type "help".
For more comprehensive documentation,see
http://docs.mongodb.org/
Questions? Try the support group
http://groups.google.com/group/mongodb-user
Server has startup warnings: 2017-07-13T20:13:28.423-0700 I CONTROL [initandlisten] 2017-07-13T20:13:28.457-0700 I CONTROL [initandlisten] ** WARNING: Access control is not enabled for the database. 2017-07-13T20:13:28.459-0700 I CONTROL [initandlisten] ** Read and write access to data and configuration is unrestricted. 2017-07-13T20:13:28.486-0700 I CONTROL [initandlisten]
创建数据库 > use superWANG switched to db superWANG > db superWANG 向数据库插入数据 > db.superWang.insert({"name":"golang"})
WriteResult({ "nInserted" : 1 })
查看所有数据库 > show dbs
admin 0.000GB
local 0.000GB
superWANG 0.000GB
删除数据库 > db.dropDatabase()
{ "dropped" : "superWANG","ok" : 1 }
> show dbs
admin 0.000GB
local 0.000GB
golang中使用MongoDBmgo(音mango)是MongoDB的Go语言驱动,它用基于Go语法的简单API实现了丰富的特性,并经过良好测试。 文档 获取 go get gopkg.in/mgo.v2
连接 session,err := mgo.Dial(url) 切换数据库 db := session.DB("test")
切换集合 通过Database.C()方法切换集合(Collection)。 func (db Database) C(name string) Collection
插入 func (c *Collection) Insert(docs ...interface{}) error
c := session.DB("store").C("books")
err = c.Insert(book)
查询 func (c Collection) Find(query interface{}) Query
更新 c := session.DB("store").C("books")
err = c.Update(bson.M{"isbn": isbn},&book)
查询所有 c := session.DB("store").C("books")
var books []Book
err := c.Find(bson.M{}).All(&books)
删除 c := session.DB("store").C("books")
err := c.Remove(bson.M{"isbn": isbn})
应用 package main
import (
"fmt"
"log"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
type Person struct {
Name string
Phone string
}
func main() {
session,err := mgo.Dial("localhost:27017")
if err != nil {
panic(err)
}
defer session.Close()
// Optional. Switch the session to a monotonic behavior.
session.SetMode(mgo.Monotonic,true)
c := session.DB("test").C("people")
err = c.Insert(&Person{"superWang","13478808311"},&Person{"David","15040268074"})
if err != nil {
log.Fatal(err)
}
result := Person{}
err = c.Find(bson.M{"name": "superWang"}).One(&result)
if err != nil {
log.Fatal(err)
}
fmt.Println("Name:",result.Name)
fmt.Println("Phone:",result.Phone)
}
输出: Microservice with MongoDB in Go再来点实战的,使用mongodb做一个微服务,这里使用Goji. 什么是Goji? 获取 go get goji.io
使用 package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"goji.io"
"goji.io/pat"
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
)
func ErrorWithJSON(w http.ResponseWriter,message string,code int) {
w.Header().Set("Content-Type","application/json; charset=utf-8")
w.WriteHeader(code)
fmt.Fprintf(w,"{message: %q}",message)
}
func ResponseWithJSON(w http.ResponseWriter,json []byte,"application/json; charset=utf-8")
w.WriteHeader(code)
w.Write(json)
}
type Book struct {
ISBN string `json:"isbn"`
Title string `json:"title"`
Authors []string `json:"authors"`
Price string `json:"price"`
}
func main() {
session,err := mgo.Dial("localhost:27017")
if err != nil {
panic(err)
}
defer session.Close()
session.SetMode(mgo.Monotonic,true)
ensureIndex(session)
mux := goji.NewMux()
mux.HandleFunc(pat.Get("/books"),allBooks(session))
mux.HandleFunc(pat.Post("/books"),addBook(session))
mux.HandleFunc(pat.Get("/books/:isbn"),bookByISBN(session))
mux.HandleFunc(pat.Put("/books/:isbn"),updateBook(session))
mux.HandleFunc(pat.Delete("/books/:isbn"),deleteBook(session))
http.ListenAndServe("localhost:8080",mux)
}
func ensureIndex(s *mgo.Session) {
session := s.Copy()
defer session.Close()
c := session.DB("store").C("books")
index := mgo.Index{
Key: []string{"isbn"},Unique: true,DropDups: true,Background: true,Sparse: true,}
err := c.EnsureIndex(index)
if err != nil {
panic(err)
}
}
func allBooks(s *mgo.Session) func(w http.ResponseWriter,r *http.Request) {
return func(w http.ResponseWriter,r *http.Request) {
session := s.Copy()
defer session.Close()
c := session.DB("store").C("books")
var books []Book
err := c.Find(bson.M{}).All(&books)
if err != nil {
ErrorWithJSON(w,"Database error",http.StatusInternalServerError)
log.Println("Failed get all books: ",err)
return
}
respBody,err := json.MarshalIndent(books,""," ")
if err != nil {
log.Fatal(err)
}
ResponseWithJSON(w,respBody,http.StatusOK)
}
}
func addBook(s *mgo.Session) func(w http.ResponseWriter,r *http.Request) {
session := s.Copy()
defer session.Close()
var book Book
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&book)
if err != nil {
ErrorWithJSON(w,"Incorrect body",http.StatusBadRequest)
return
}
c := session.DB("store").C("books")
err = c.Insert(book)
if err != nil {
if mgo.IsDup(err) {
ErrorWithJSON(w,"Book with this ISBN already exists",http.StatusBadRequest)
return
}
ErrorWithJSON(w,http.StatusInternalServerError)
log.Println("Failed insert book: ",err)
return
}
w.Header().Set("Content-Type","application/json")
w.Header().Set("Location",r.URL.Path+"/"+book.ISBN)
w.WriteHeader(http.StatusCreated)
}
}
func bookByISBN(s *mgo.Session) func(w http.ResponseWriter,r *http.Request) {
session := s.Copy()
defer session.Close()
isbn := pat.Param(r,"isbn")
c := session.DB("store").C("books")
var book Book
err := c.Find(bson.M{"isbn": isbn}).One(&book)
if err != nil {
ErrorWithJSON(w,http.StatusInternalServerError)
log.Println("Failed find book: ",err)
return
}
if book.ISBN == "" {
ErrorWithJSON(w,"Book not found",http.StatusNotFound)
return
}
respBody,err := json.MarshalIndent(book,http.StatusOK)
}
}
func updateBook(s *mgo.Session) func(w http.ResponseWriter,"isbn")
var book Book
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&book)
if err != nil {
ErrorWithJSON(w,http.StatusBadRequest)
return
}
c := session.DB("store").C("books")
err = c.Update(bson.M{"isbn": isbn},&book)
if err != nil {
switch err {
default:
ErrorWithJSON(w,http.StatusInternalServerError)
log.Println("Failed update book: ",err)
return
case mgo.ErrNotFound:
ErrorWithJSON(w,http.StatusNotFound)
return
}
}
w.WriteHeader(http.StatusNoContent)
}
}
func deleteBook(s *mgo.Session) func(w http.ResponseWriter,"isbn")
c := session.DB("store").C("books")
err := c.Remove(bson.M{"isbn": isbn})
if err != nil {
switch err {
default:
ErrorWithJSON(w,http.StatusInternalServerError)
log.Println("Failed delete book: ",http.StatusNotFound)
return
}
}
w.WriteHeader(http.StatusNoContent)
}
}
测试结果 GET 所有书 GET 某本书 PUT 更新 DELETE 删除 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |