Skip to content

MongoDB

MongoDB est une base de données de documents, son unité de données de base est le document, le format de stockage est BSON (Binary JSON), une structure similaire à JSON. Sa structure souple permet de stocker différents types de données, offrant plus de flexibilité par rapport aux bases de données relationnelles. De plus, il utilise JavaScript comme langage de script, permettant d'effectuer des opérations combinées via des scripts. Cet article présente principalement l'utilisation du pilote officiel mongo dans Go pour opérer la base de données mongodb. Ce n'est pas un tutoriel mongodb, donc si vous n'avez pas de bases mongo, veuillez d'abord vous renseigner et apprendre par vous-même.

Documentation mongodb : Introduction to MongoDB — MongoDB Manual

Pilote

Il existe peu de bibliothèques Go pour mongodb. Au début, certaines bibliothèques étaient maintenues par la communauté, mais elles ont depuis arrêté leur maintenance. Cependant, le pilote officiel mongo est entièrement suffisant.

Dépôt open source : mongodb/mongo-go-driver: The Official Golang driver for MongoDB (github.com)

Adresse de la documentation : mongodb/mongo-go-driver: The Official Golang driver for MongoDB (github.com)

Installation

Pour télécharger la dépendance, utilisez l'adresse ci-dessous.

sh
$ go get go.mongodb.org/mongo-driver/mongo

Connexion

Voici un exemple simple de connexion entre un client mongo et un serveur.

go
package main

import (
   "context"
   "fmt"
   "go.mongodb.org/mongo-driver/mongo"
   "go.mongodb.org/mongo-driver/mongo/options"
   "go.mongodb.org/mongo-driver/mongo/readpref"
   "log"
)

func main() {
   ctx := context.Background()
   // Utiliser l'URI pour établir la connexion
   client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://admin:123456@192.168.48.138:27017/"))
   if err != nil {
      log.Panicln(err)
   }
   // Fermer la connexion
   defer client.Disconnect(ctx)
   // Test ping pour vérifier si la connexion est disponible
   fmt.Println(client.Ping(ctx, readpref.Primary()))
}

bson

mongodb utilise les types suivants dans Go pour mapper les documents de la base de données, situés dans bson/bson.go

go
// Représentation ordonnée d'un document BSON
type D = primitive.D

// Une paire clé-valeur, unité de base de la représentation ordonnée d'un document BSON
type E = primitive.E

// Représentation non ordonnée d'un document BSON
type M = primitive.M

// Représentation ordonnée d'un tableau BSON
type A = primitive.A

Leurs types réels sont les suivants

go
// Représentation ordonnée d'un document BSON
type D []E

// Une paire clé-valeur, unité de base de la représentation ordonnée d'un document BSON
type E struct {
  Key   string
  Value interface{}
}

// Représentation non ordonnée d'un document BSON
type M map[string]interface{}

// Représentation ordonnée d'un tableau BSON
type A []interface{}

Avec ces types, vous pouvez construire des requêtes SQL et également mapper des données.

TIP

Le répertoire examples du pilote contient de nombreux exemples d'utilisation. La documentation officielle démontre très détaillée comment utiliser ces quatre types.

Adresse : mongo-go-driver/examples/documentation_examples/examples.go at master · mongodb/mongo-go-driver (github.com)

Interroger des documents

Exemple de requête officiel : mongo-go-driver/examples/documentation_examples/examples.go at master · mongodb/mongo-go-driver (github.com)

D'abord, créez la base de données user et insérez les données suivantes dans la collection users

sql
> use user
> db.users.insertMany([
    {
        name: "mike",
        age: 12,

    },
    {
        name: "jenny",
        age: 14,

    },
    {
        name: "jack",
        age: 18,
        address: "usa"
    }
])

Interroger un seul document

go
type User struct {
    Name    string `bson:"name"`
    Age     int    `bson:"age"`
    Address string `bson:"address"`
}

var user User

result := client.Database("user"). // Sélectionner la base de données
                    Collection("users").                     // Sélectionner la collection
                    FindOne(ctx, bson.D{{"address", "usa"}}) // Condition de filtrage

// Désérialisation
if err := result.Decode(&user); err != nil {
    log.Panicln(err)
}

fmt.Printf("%+v\n", user)

Le code de requête ci-dessus est équivalent à

sql
db.users.findOne({
    address: "usa"
})

Résultat de la sortie

{Name:jack Age:18 Address:usa}

Interroger plusieurs documents

go
type User struct {
   Name    string `bson:"name"`
   Age     int    `bson:"age"`
   Address string `bson:"address"`
}

var users []User

cursor, err := client.Database("user"). // Sélectionner la base de données
               Collection("users"). // Sélectionner la collection
               Find(ctx, bson.D{})  // Condition de filtrage

if err != nil {
   log.Panicln(err)
}

if err := cursor.All(ctx, &users); err != nil {
   log.Panicln(err)
}

fmt.Printf("%+v\n", users)

Équivalent à

sql
db.users.find({})

Sortie

[{Name:jack Age:18 Address:usa} {Name:mike Age:12 Address:} {Name:jenny Age:14 Address:}]

Lors de la construction de conditions de requête, vous pouvez également utiliser des options

go
type User struct {
    Name    string `bson:"name"`
    Age     int    `bson:"age"`
    Address string `bson:"address"`
}

var users []User

find := options.Find()
find.SetSort(bson.M{"age": 1})
find.SetLimit(1)

cursor, err := client.Database("user"). // Sélectionner la base de données
                    Collection("users").      // Sélectionner la collection
                    Find(ctx, bson.D{}, find) // Condition de filtrage

if err != nil {
    log.Panicln(err)
}

if err := cursor.All(ctx, &users); err != nil {
    log.Panicln(err)
}

fmt.Printf("%+v\n", users)

Équivalent à

db.users.find({}).sort({age:1}).limit(1)

Sortie

[{Name:mike Age:12 Address:}]

Créer des documents

Exemple de création officiel : mongo-go-driver/examples/documentation_examples/examples.go at master · mongodb/mongo-go-driver (github.com)

Voici un exemple de création d'un document

go
one, err := client.Database("user").Collection("users").InsertOne(ctx, User{
    Name:    "lili",
    Age:     20,
    Address: "china",
})
if err != nil {
    log.Panicln(err)
}
fmt.Println(one.InsertedID)

Après une création réussie, l'ObjectID du document est retourné

ObjectID("64c60fa01e2548d9e4de6cf4")

Voici un exemple de création de plusieurs documents

go
users := []any{User{
    Name:    "john",
    Age:     10,
    Address: "usa",
}, User{
    Name:    "pop",
    Age:     30,
    Address: "uk",
}}

one, err := client.Database("user").Collection("users").InsertMany(ctx, users)
if err != nil {
    log.Panicln(err)
}
fmt.Println(one.InsertedIDs)

Après une création réussie, un groupe d'ObjectID est retourné

[ObjectID("64c610d5aec2618d6ca0b515") ObjectID("64c610d5aec2618d6ca0b516")]

Les deux morceaux de code ci-dessus sont équivalents à db.users.insertOne et db.users.insertMany.

Mettre à jour des documents

Exemple de mise à jour officiel : mongo-go-driver/examples/documentation_examples/examples.go at master · mongodb/mongo-go-driver (github.com)

Voici un exemple de mise à jour d'un seul document, renommant la personne nommée lili en mark

go
upres, err := client.Database("user").Collection("users").UpdateOne(ctx, bson.D{
    {"name", "mark"},
},
    bson.D{
       {"$set", bson.D{
          {"name", "lili"},
       }},
    })
if err != nil {
    log.Panicln(err)
}
fmt.Printf("%+v", upres)

Équivalent à

sql
db.users.updateOne({
    name: "lili"
}, {
    $set: {
        name: "mark"
    },
})

Sortie

&{MatchedCount:1 ModifiedCount:1 UpsertedCount:0 UpsertedID:<nil>}

Voici un exemple de mise à jour de plusieurs documents, mettant à jour l'adresse des personnes de 10 ans à cn

go
upres, err := client.Database("user").Collection("users").UpdateMany(ctx, bson.D{
    {"age", 10},
},
    bson.D{
        {"$set", bson.D{
            {"address", "cn"},
        }},
    })
if err != nil {
    log.Panicln(err)
}
fmt.Printf("%+v", upres)

En plus d'utiliser Update, mongo fournit également Replace. La différence entre les deux est que le premier met à jour les champs du document, tandis que le second remplace directement le document. Par exemple, dans le code suivant, vous n'avez plus besoin d'opérateur.

go
upres, err := client.Database("user").Collection("users").ReplaceOne(ctx, bson.D{
    {"age", 10},
},
    bson.D{
       {"address", "cn"},
    })
if err != nil {
    log.Panicln(err)
}
fmt.Printf("%+v", upres)

Mongo fournit également FindOneAndUpdate et FindOneAndReplace pour récupérer et mettre à jour des documents. Comme suit

go
res := client.Database("user").Collection("users").FindOneAndReplace(ctx, bson.D{
    {"address", "cn"},
},
    bson.D{
       {"address", "uk"},
    })
if err := res.Err(); err != nil {
    log.Panicln(err)
}

var user User

res.Decode(&user)

fmt.Printf("%+v", user)

Sortie

Name: Age:0 Address:cn}

Cette opération va d'abord interroger le document puis le modifier.

Supprimer des documents

Exemple de suppression officiel : mongo-go-driver/examples/documentation_examples/examples.go at master · mongodb/mongo-go-driver (github.com)

Voici un exemple de suppression d'un document

go
result, err := client.Database("user").Collection("users").DeleteOne(ctx, bson.D{
    {"name", "jack"},
})
if err != nil {
    log.Panicln(err)
}
fmt.Println(result.DeletedCount)

Voici un exemple de suppression de plusieurs documents

go
result, err := client.Database("user").Collection("users").DeleteMany(ctx, bson.D{
    {"age", "10"},
})
if err != nil {
    log.Panicln(err)
}
fmt.Println(result.DeletedCount)

Agrégation

Exemple d'agrégation officiel : mongo-go-driver/examples/documentation_examples/examples.go at master · mongodb/mongo-go-driver (github.com)

Les opérations d'agrégation utilisent le type mongo.Pipeline, qui est essentiellement []bson.D

go
type Pipeline []bson.D
go
pipline := mongo.Pipeline{
    {
       {"$match", bson.D{
          {"address", "uk"},
       }},
    },
    {
       {"$sort", bson.D{
          {"age", 1},
       }},
    },
}
aggregate, err := client.Database("user").Collection("users").Aggregate(ctx, pipline)
if err != nil {
    log.Panicln(err)
}
var users []User
if err := aggregate.All(ctx, &users); err != nil {
    log.Panicln(err)
}
log.Println(users)

Sortie

[{lili 20 uk} {kak 30 uk}]

Cette opération d'agrégation correspond à tous les utilisateurs dont l'adresse est uk, puis les trie par âge.

Golang by www.golangdev.cn edit