През март 2019 г. беше пуснат официалният, готов за производство GO драйвер за MongoDB и получаваше непрекъснати актуализации от стартирането му. В този урок ще се научим да правим прости операции на MongoDB CRUD с помощта на Go драйвер.
Предварителни условия
Необходими са две неща, преди да започнем с този урок.
- Go трябва да бъде инсталиран на вашето устройство. Go версия 1.15 се използва за този урок. Можете да изтеглите пакета Go от тази връзка.
- Инсталирайте най-новата версия на MongoDB на вашата машина и стартирайте локалния сървър на MongoDB.
Инсталиране на драйвера MongoDB
Инсталирайте драйвера MongoDB go, като изпълните следната команда:
go get go.mongodb.org/mongo-driver
Ако използвате Go Modules, тогава създайте файл go.mod и след това горната команда ще добави необходимата зависимост във файла на мода. Този файл заключва всички изисквания на проекта към правилната му версия.
Настройка на основния файл
Създайте файл main.go в папката на вашия проект и го отворете във вашата IDE. Преди да напишем кода за операциите на MongoDB, нека импортираме всички необходими пакети във файла.
package main
import (
"context"
"fmt"
"log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
Сега създайте следните глобални променливи, които ще използваме във всички CRUD операционни функции.
var client *mongo.Client
var collection *mongo.Collection
var ctx = context.TODO()
Освен това създайте структурата за типа документ.
type Person struct {
Name string
Age int
City string
}
Свързвам се с MongoDB
Сега базовата настройка е готова. Нека създадем първата ни функция за свързване с MongoDB.
func connect() *mongo.Client {
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
client, err := mongo.Connect(ctx, clientOptions)
if err != nil {
log.Fatal(err)
}
err = client.Ping(ctx, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println("Connected to MongoDB!")
return client
}
Тази функция ще настрои връзката с нашия локално работещ MongoDB и ще върне клиентския обект. След като методът за свързване върне клиентския обект, можем да използваме метода Ping(), за да проверим дали връзката е била успешна или не. Ако методът Ping() върне някаква грешка, можем да повдигнем грешката и да върнем.
Операция за вмъкване
За да вмъкнем само един документ, можем да използваме метода insertOne, а за да вмъкнем няколко документа заедно, можем да използваме метода insertMany. Следва функцията за вмъкване на един документ в колекцията Лица:
func insertOne() {
akash := Person{"Akash", 28, "Bengaluru"}
res, err := collection. InsertOne (ctx, akash)
if err != nil {
log.Fatal(err)
}
fmt.Println("Inserted document: ", res.InsertedID)
}
Ето функцията за добавяне на множество документи към колекцията:
func insertMany() {
akash := Person{"Akash", 28, "Bengaluru"}
bob := Person {"Bob", 30, "New York"}
robin := Person {"Robin", 25, "London"}
persons := []interface{}{akash, bob, robin}
res, err := collection.InsertMany(ctx, persons)
if err != nil {
log.Fatal(err)
}
fmt.Println("Inserted documents: ", res.InsertedIDs)
}
И за двете операции трябва да използваме структурата Person, която създадохме по-рано, и да я инициализираме с нашите данни. С функцията InsertMany ще изискваме да предадем интерфейса на типа за всички документи.
Операция за извличане
За намиране на данни от колекцията ще ни е необходим пропусков филтър, така че се уверете, че сте импортирали пакета bson. Ще използваме тип bson.D, за да създадем филтри, използвайки bson обекти.
func retrieveOne() {
var result Person
filter := bson.D{{"name", "Akash"}}
err := collection.FindOne(ctx, filter).Decode(&result)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Found a single document: %+v\n", result)
}
По същия начин можем да използваме метода Find, за да извлечем всички съответстващи документи.
func retrieveAll() {
findOptions := options.Find()
findOptions.SetLimit(2)
var results []*Person
cur, err := collection.Find(ctx, bson.D{{}}, findOptions)
if err != nil {
log.Fatal(err)
}
// Loop through the cursor
for cur.Next(context.TODO()) {
var elem Person
err := cur.Decode(&elem)
if err != nil {
log.Fatal(err)
}
results = append(results, &elem)
}
if err := cur.Err(); err != nil {
log.Fatal(err)
}
cur.Close(context.TODO())
}
Можете да използвате пакета с опции, за да посочите опции като лимит или поръчки.
Операция за актуализиране
Същото като метода FineOne, за актуализиране също можете да използвате метода UpdateOne с обект на филтър bson. Този код ще актуализира всички документи с името Akash и ще увеличи стойността на Age с едно.
func update() {
filter := bson.D{{"name", "Akash"}}
update := bson.D{
{"$inc", bson.D{
{"Age", 1},
}},
}
updateResult, err := collection.UpdateOne(context.TODO(), filter, update)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Updated documents: %+v\n", updateResult)
}
Операция изтриване
За изтриване на документи от която и да е колекция можете да използвате метода DeleteOne или DeleteMany. Тук също можем да подадем bson филтърни обекти, за да съответстват на документите и да ги изтрием.
func delete() {
deleteResult, err := collection.DeleteMany(ctx, bson.D{{}})
if err != nil {
log.Fatal(err)
}
fmt.Printf("Deleted %v documents in the trainers collection\n", deleteResult.DeletedCount)
}
Ако предадете bson.D{{}} обект като филтърен параметър, тогава той ще изтрие всички документи. Можете да използвате метода collection.Drop(), за да пуснете цялата колекция.
След като всички тези функции са готови, можете да ги използвате във функцията на драйвера според вашите нужди. Надяваме се, че това ще бъде достатъчно, за да започнете да пишете функции на MongoDB в Go. За повече информация можете да се обърнете към официалната документация за драйвера Go Mongo.