go use mongodb

What is MongoDB?

Introduction 
MongoDB is written in C++ language and is an open source database system based on distributed file storage. 
In the case of high load, adding more nodes can guarantee the server performance. 
MongoDB aims to provide a scalable, high-performance data storage solution for web applications. 
MongoDB stores data as a document, and the data structure consists of key-value (key=>value) pairs. MongoDB documents are similar to JSON objects

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.

Features 
MongoDB provides a document-oriented store that is relatively simple and easy to operate.

You can set an index on any attribute in a MongoDB record (eg: FirstName=”Sameer”, Address=”8 Gandhi Road”) to achieve faster sorting.

You can create data mirroring locally or over the network, which makes MongoDB more scalable.

If the load increases (more storage space and more processing power are required), it can be distributed among other nodes in the computer network. This is called sharding.

Mongo supports rich query expressions. The query command uses JSON format markup to easily query objects and arrays embedded in the document.

MongoDb can use the update() command to replace the completed document (data) or some specified data fields.

Map/reduce in Mongodb is mainly used for batch processing and aggregation operations on data.

Map and Reduce. The Map function calls emit(key, value) to traverse all the records in the collection, and passes the key and value to the Reduce function for processing.

Map functions and Reduce functions are written in Javascript and can execute MapReduce operations through db.runCommand or mapreduce commands.

GridFS is a built-in feature in MongoDB that can be used to store large numbers of small files.

MongoDB allows scripts to be executed on the server side. You can write a function in Javascript and execute it directly on the server side. You can also store the definition of the function on the server side and call it directly next time.

MongoDB supports various programming languages: RUBY, PYTHON, JAVA, C++, PHP, C# and many other languages.

MongoDB is easy to install.

Comparison of 
MongoDB and Redis Both MongoDB and Redis are NoSQL, using structured data storage. There are certain differences between the two in usage scenarios, which is mainly due to the different processing methods of memory mapping and persistence between the two.

MongoDB recommends cluster deployment. Considering the cluster solution more, Redis prefers process sequential writing. Although it supports clustering, it is limited to master-slave mode.

When to use Redis?

Caching 
Caching using MongoDB simply doesn’t make a lot of sense. It would be too slow.

If you have enough time to think about your DB design. 
You can’t simply throw in your documents into Redis. You have to think of the way you in which you want to store and organize your data. One example are hashes in Redis. They are quite different from “traditional”, nested objects, which means you’ll have to rethink the way you store nested documents. One solution would be to store a reference inside the hash to another hash (something like key: [id of second hash]). Another idea would be to store it as JSON, which seems counter-intuitive to most people with a *SQL-background.

If you need really high performance. 
Beating the performance Redis provides is nearly impossible. Imagine you database being as fast as your cache. That’s what it feels like using Redis as a real database.

If you don’t care that much about scaling. 
Scaling Redis is not as hard as it used to be. For instance, you could use a kind of proxy server in order to distribute the data among multiple Redis instances. Master-slave replication is not that complicated, but distributing you keys among multiple Redis-instances needs to be done on the application site (e.g. using a hash-function, Modulo etc.). Scaling MongoDB by comparison is much simpler.

When to use MongoDB

Prototyping, Startups, Hackathons 
MongoDB is perfectly suited for rapid prototyping. Nevertheless, performance isn’t that good. Also keep in mind that you’ll most likely have to define some sort of schema in your application.

When you need to change your schema quickly. 
Because there is no schema! Altering tables in traditional, relational DBMS is painfully expensive and slow. MongoDB solves this problem by not making a lot of assumptions on your underlying data. Nevertheless, it tries to optimize as far as possible without requiring you to define a schema.

Install MongoDB under Windows

Official website: 
https://www.mongodb.com/ 
Download address: 
https://www.mongodb.com/download-center#community

write picture description here

Add the installation location to the environment variable, for example: 
D:\Program Files\MongoDB\Server\3.4\bin

At the command line type:

C:\Users\wangs>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

Start the mongodb service 
to create a directory, and then set it as the data directory of mongodb: 
for example: D:\mongodb_data\db

At the command line type:

C:\Users\wangs>mongod.exe --dbpath d:\mongodb_data\db
2017-07-13T20:10:37.851-0700 I CONTROL  [initandlisten] MongoDB starting : pid=5524 port=27017 dbpath=d:\mongodb_data\db 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_data\db" } }
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

Client connects to mongodb

C:\Users\wangs>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]

create database

> use superWANG
switched to db superWANG
> db
superWANG

Insert data into database

> db.superWang.insert({"name":"golang"})
WriteResult({ "nInserted" : 1 })

View all databases

> show dbs
admin      0.000GB
local      0.000GB
superWANG  0.000GB

delete database

> db.dropDatabase()
{ "dropped" : "superWANG", "ok" : 1 }
> show dbs
admin  0.000GB
local  0.000GB

Using MongoDB in golang

mgo (pronounced mango) is the Go language driver for MongoDB, which implements rich features with a simple API based on Go syntax and is well tested.

Documentation  
http://godoc.org/labix.org/v2/mgo

Obtain

go get gopkg.in/mgo.v2

connect

session, err := mgo.Dial(url)

switch database

db := session.DB("test")

toggle collection

Switch the collection (Collection) through the Database.C() method.

func (db Database) C(name string) Collection

insert

func (c *Collection) Insert(docs ...interface{}) error
c := session.DB("store").C("books")  
err = c.Insert(book)  

Inquire

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

renew

c := session.DB("store").C("books")  
err = c.Update(bson.M{"isbn": isbn}, &book)

query all

c := session.DB("store").C("books")

var books []Book
err := c.Find(bson.M{}).All(&books)

delete

c := session.DB("store").C("books")
err := c.Remove(bson.M{"isbn": isbn})

application

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)
}

Output: 
Name: superWang 
Phone: 13478808311

Microservice with MongoDB in Go

A little more practical, use mongodb to make a microservice, and use Goji here.

什么是Goji? 
Goji is a HTTP request multiplexer, similar to net/http.ServeMux. It compares incoming requests to a list of registered Patterns, and dispatches to the Handler that corresponds to the first matching Pattern. Goji also supports Middleware (composable shared functionality applied to every request) and uses the standard context to store request-scoped values.

Obtain

go get goji.io

use

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, code int) {
    w.Header().Set("Content-Type", "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) {
    return 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, "Database error", 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) {
    return 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, "Database error", 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, "", "  ")
        if err != nil {
            log.Fatal(err)
        }

        ResponseWithJSON(w, respBody, http.StatusOK)
    }
}

func updateBook(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) {
    return func(w http.ResponseWriter, r *http.Request) {
        session := s.Copy()
        defer session.Close()

        isbn := pat.Param(r, "isbn")

        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.Update(bson.M{"isbn": isbn}, &book)
        if err != nil {
            switch err {
            default:
                ErrorWithJSON(w, "Database error", http.StatusInternalServerError)
                log.Println("Failed update book: ", err)
                return
            case mgo.ErrNotFound:
                ErrorWithJSON(w, "Book not found", http.StatusNotFound)
                return
            }
        }

        w.WriteHeader(http.StatusNoContent)
    }
}

func deleteBook(s *mgo.Session) func(w http.ResponseWriter, r *http.Request) {
    return func(w http.ResponseWriter, r *http.Request) {
        session := s.Copy()
        defer session.Close()

        isbn := pat.Param(r, "isbn")

        c := session.DB("store").C("books")

        err := c.Remove(bson.M{"isbn": isbn})
        if err != nil {
            switch err {
            default:
                ErrorWithJSON(w, "Database error", http.StatusInternalServerError)
                log.Println("Failed delete book: ", err)
                return
            case mgo.ErrNotFound:
                ErrorWithJSON(w, "Book not found", http.StatusNotFound)
                return
            }
        }

        w.WriteHeader(http.StatusNoContent)
    }
}

Test result 
POST 
write picture description here

GET all books 
write picture description here

GET a book 
write picture description here

PUT update 
write picture description here

DELETE delete 
write picture description here

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325405801&siteId=291194637