# Golang -- Backend (Sprint1) contributed by < `ArielWu0203` > ###### tags: `Backend` [GitHub : pd1-learning](https://github.com/ArielWu0203/pd1-learning) ## Goal - [x] Set up endpoint service on [localhost](http://localhost) with port 3000 - [x] Set up a hello world page sent back from `http://localhost:3000/` - [x] Create the `Problems` collection in MongoDB with Robomongo - [x] Create several documents with the following attributes - [x] Pid (int) - [x] Title (String) - [x] Solution (Boolean) - [x] Acceptance (Float) - [x] Complete the function of the endpoint `GET http://localhost/api/problem` that retreives the data from MongoDB with MongoDB-go-driver ## Install the MongoDB Go Driver ```= $ cd go/src $ go get go.mongodb.org/mongo-driver ``` ## Connect to DB ```go= // Set client options // options.Client() : creates a new ClientOptions instance. clientOptions := options.Client().ApplyURI("mongodb://localhost:27017") // Connect to MongoDB client, err := mongo.Connect(context.TODO(), clientOptions) if err != nil { log.Fatal(err) } // Check the connection err = client.Ping(context.TODO(), nil) if err != nil { log.Fatal(err) } fmt.Println("Connected to MongoDB!") ``` * context * context switch : 當使用權要從 A process 交給 B process 時,A process 的狀態需要被保存下來,記錄在 PCB 中,再載入 B process 。 * context.Background() : * 已先初始化。 * return non-nil, empty Context. * No canceled, No value, No deadline. * 通常用在 main function, top-level Context, parent Context. * context,TODO() : * 已先初始化。 * return non-nil, empty Context. * 不清楚、不確定時才使用。 * More links * [package context](https://godoc.org/context) * [上下文 Context](https://draveness.me/golang/concurrency/golang-context.html) * [examples : Golang Context](https://juejin.im/post/5a6873fef265da3e317e55b6) * Collection ```go= collection := client.Database(db_name).Collection(collection_name) ``` * Disconnect ```go= err = client.Disconnect(context.TODO()) if err != nil { log.Fatal(err) } fmt.Println("Connection to MongoDB closed.") ``` ## Insert Documents ```go= func ExampleInsertDocs(collection *mongo.Collection) { // Create several documents in DB Doc1 := Problem{1, "Zuma Game", false, 40.2} Doc2 := Problem{2, "Word Subsets", true, 46.2} Doc3 := Problem{3, "Word Search", false, 32.9} Docs := []interface{}{Doc1, Doc2, Doc3} insertResult, err := collection.InsertMany(context.TODO(), Docs) if err != nil { log.Fatal(err) } fmt.Println("Docs: ", insertResult.InsertedIDs) } ``` ## FindOneDoc ```go= var problem Problem filter := bson.M {"pid" : number} ctx, _ := context.WithTimeout(context.Background(), 5*time.Second) err := collection.FindOne(ctx, filter).Decode(&problem) if err != nil { log.Fatal(err) } ``` * BSON Objects * Binary-encoded JSON * Type : * D: A BSON document. This type should be used in situations where order matters, such as MongoDB commands. * M: An unordered map. It is the same as D, except it does not preserve order. * A: A BSON array. * E: A single element inside a D. ## FindAllDocs ```go= findOptions := options.Find() findOptions.SetLimit(10) var results []*Problem cur, err := collection.Find(context.TODO(), bson.D{{}}, findOptions) if err != nil { log.Fatal(err) } for cur.Next(context.TODO()) { var elem Problem err := cur.Decode(&elem) if err != nil { log.Fatal(err) } results = append(results, &elem) } if err := cur.Err(); err != nil { log.Fatal(err) } ``` * More Links * [func (*Collection) Find](https://godoc.org/go.mongodb.org/mongo-driver/mongo#Connect) ## Reference * [GitHub : MongoDB Go Driver](https://github.com/mongodb/mongo-go-driver) * [Doc : MongoDB Go Driver](https://godoc.org/go.mongodb.org/mongo-driver/mongo)