蓝星世界 發表於 2025-12-15 10:44:48

Golang查询MongoDB的实现步骤

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">使用 Golang 向 MongoDB 插入文档</a></li><li><a href="#_label1">使用 Golang 向 MongoDB 写入多个文档</a></li><li><a href="#_label2">使用 Golang 从 MongoDB 中查找单个文档</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_0">获取最后创建的文档</a></li></ul><li><a href="#_label3">使用 Golang 从 MongoDB 中查找所有文档</a></li><ul class="second_class_ul"><li><a href="#_lab2_3_1">查找符合条件的多个文档</a></li><li><a href="#_lab2_3_2">在查找操作中使用Projection</a></li></ul><li><a href="#_label4">使用 Golang 更新 MongoDB 中的单个文档</a></li><ul class="second_class_ul"><li><a href="#_lab2_4_3">如何在 MongoDB 中返回更新的文档?</a></li></ul><li><a href="#_label5">使用 Golang 从 MongoDB 中删除文档</a></li><ul class="second_class_ul"></ul><li><a href="#_label6">原文地址</a></li><ul class="second_class_ul"></ul></ul></div><p>连接 MongoDB 非常简单,只需连接 MongoDB 生成的 uri。</p>
<p>然后我们可以使用 <a href="https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo" rel="external nofollow"   target="_blank">client.Database()</a> 函数来确保我们连接到正确的数据库。</p>
<div class="jb51code"><pre class="brush:go;">package main

import (
        "context"
        "log"
        "time"

        "go.mongodb.org/mongo-driver/mongo"
        "go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        defer cancel()

        client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
        if err != nil {
                log.Fatal(err)
        }

        db := client.Database("testdb")

        // disconnect the mongo client when main is completed
        defer func() {
                if err = client.Disconnect(ctx); err != nil {
                        panic(err)
                }
        }()
}
</pre></div>
<p>我们可以使用<code>Ping</code>方法来真正确保我们连接到正确的数据库。</p>
<div class="jb51code"><pre class="brush:go;">ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second)
defer cancel()

err = client.Ping(ctx, readpref.Primary())
</pre></div>
<p class="maodian"><a name="_label0"></a></p><h2>使用 Golang 向 MongoDB 插入文档</h2>
<p>要将文档插入 MongoDB,我们可以使用MongoDB 提供的 <a href="https://pkg.go.dev/go.mongodb.org/mongo-driver/bson" rel="external nofollow"   target="_blank">bson.D</a>。但为了使操作更简单、更贴近实际应用,我们将使用<code>bson</code>注解标注<code>struct</code>。</p>
<p>我们使用的模型是:</p>
<div class="jb51code"><pre class="brush:go;">type Car struct {
        Id    primitive.ObjectID `bson:"_id"`
        Brand string             `bson:"brand"`
        Model string             `bson:"model"`
        Yearint                `bson:"year"`
}
</pre></div>
<p>然后我们可以简单地使用 <a href="https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo" rel="external nofollow">InsertOne()</a>方法 将文档插入 MongoDB。</p>
<div class="jb51code"><pre class="brush:go;">package main

import (
        "context"
        "log"
        "time"

        "go.mongodb.org/mongo-driver/bson/primitive"
        "go.mongodb.org/mongo-driver/mongo"
        "go.mongodb.org/mongo-driver/mongo/options"
)

type Car struct {
        Id      primitive.ObjectID `bson:"_id"`
    CreatedAt time.Time          `bson:"createdAt"`
        Brand   string             `bson:"brand"`
        Model   string             `bson:"model"`
        Year      int                `bson:"year"`
}

func main() {
        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        defer cancel()

        client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
        if err != nil {
                log.Fatal(err)
        }

        db := client.Database("testdb")

        exampleData := Car{
                Id:    primitive.NewObjectID(),
      CreatedAt: time.Now().UTC(),
                Brand: "Mercedes",
                Model: "G-360",
                Year:2002,
        }

        res, err := db.Collection("cars").InsertOne(context.Background(), exampleData)
        if err != nil {
                log.Fatal(err)
        }

        // inserted id is ObjectID("639b62ae2518fbd9315e405d")
        log.Printf("inserted id is %v", res.InsertedID)
}
</pre></div>
<p class="maodian"><a name="_label1"></a></p><h2>使用 Golang 向 MongoDB 写入多个文档</h2>
<p>我们可以使用 <a href="https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo" rel="external nofollow"   target="_blank">Collection</a>对象 的 <a href="https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo.InsertMany" rel="external nofollow"   target="_blank">InsertMany()</a>方法。但是,<code>InsertMany()</code>方法需要传入<code>[]interface{}</code>参数。</p>
<div class="jb51code"><pre class="brush:go;">package main

import (
        "context"
        "log"
        "time"

        "go.mongodb.org/mongo-driver/bson/primitive"
        "go.mongodb.org/mongo-driver/mongo"
        "go.mongodb.org/mongo-driver/mongo/options"
)

type Car struct {
        Id      primitive.ObjectID `bson:"_id"`
    CreatedAt time.Time          `bson:"createdAt"`
        Brand   string             `bson:"brand"`
        Model   string             `bson:"model"`
        Year      int                `bson:"year"`
}

func main() {
        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        defer cancel()

        client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
        if err != nil {
                log.Fatal(err)
        }

        db := client.Database("testdb")

        var data []interface{}
        data = append(data, Car{
                Id:    primitive.NewObjectID(),
      CreatedAt: time.Now().UTC(),
                Brand: "Toyota",
                Model: "Corolla",
                Year:2008,
        })
        data = append(data, Car{
                Id:    primitive.NewObjectID(),
      CreatedAt: time.Now().UTC(),
                Brand: "Ford",
                Model: "Focus",
                Year:2021,
        })

        res, err := db.Collection("cars").InsertMany(context.Background(), data)
        if err != nil {
                log.Fatal(err)
        }

        // 2 documents inserted
        log.Printf("%v documents inserted", len(res.InsertedIDs))
}
</pre></div>
<p class="maodian"><a name="_label2"></a></p><h2>使用 Golang 从 MongoDB 中查找单个文档</h2>
<p>要查找符合条件的单个文档,我们可以使用<code>*Collection</code>对象的 <a href="https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo.FindOne" rel="external nofollow"   target="_blank">FindOne()</a>方法。</p>
<div class="jb51code"><pre class="brush:go;">package main

import (
        "context"
        "log"
        "time"

        "go.mongodb.org/mongo-driver/bson/primitive"
        "go.mongodb.org/mongo-driver/mongo"
        "go.mongodb.org/mongo-driver/mongo/options"
)

type Car struct {
        Id      primitive.ObjectID `bson:"_id"`
    CreatedAt time.Time          `bson:"createdAt"`
        Brand   string             `bson:"brand"`
        Model   string             `bson:"model"`
        Year      int                `bson:"year"`
}

func main() {
        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        defer cancel()

        client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
        if err != nil {
                log.Fatal(err)
        }

        db := client.Database("testdb")

    condition := bson.M{}
    cur, err := db.Collection("cars").FindOne(context.Background(), condition)
        if err != nil {
                log.Fatal(err)
        }

        var data []Car
        if err := cur.All(context.Background(), &amp;data); err != nil {
                log.Fatal(err)
        }

        // now we can use the data array, which contains all of the documents
        for _, car := range data {
                log.Printf("the brand is %v\n", car.Brand)
        }
}
</pre></div>
<p class="maodian"><a name="_lab2_2_0"></a></p><h3>获取最后创建的文档</h3>
<p>我们还可以将 <a href="https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo/options" rel="external nofollow">mongo.Options</a> 传递给 <code>Find()</code>方法。</p>
<p>假设我们想要获取最后插入的文档。</p>
<ul><li>我们需要按<code>createdAt</code>字段排序</li><li>它应该是降序的,这就是我们将排序值设为<code>-1</code>的原因。</li></ul>
<p class="maodian"><a name="_label3"></a></p><h2>使用 Golang 从 MongoDB 中查找所有文档</h2>
<p>要查找集合中的所有文档,我们可以使用<code>*Collection</code>对象的<a href="https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo.Find" rel="external nofollow">Find()</a>方法。</p>
<p>在下面的示例中,我们没有指定任何条件,这意味着返回数据库中的所有文档。</p>
<div class="jb51code"><pre class="brush:go;">package main

import (
        "context"
        "log"
        "time"

        "go.mongodb.org/mongo-driver/bson/primitive"
        "go.mongodb.org/mongo-driver/mongo"
        "go.mongodb.org/mongo-driver/mongo/options"
)

type Car struct {
        Id      primitive.ObjectID `bson:"_id"`
    CreatedAt time.Time          `bson:"createdAt"`
        Brand   string             `bson:"brand"`
        Model   string             `bson:"model"`
        Year      int                `bson:"year"`
}

func main() {
        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        defer cancel()

        client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
        if err != nil {
                log.Fatal(err)
        }

        db := client.Database("testdb")

    condition := bson.M{}
    cur, err := db.Collection("cars").Find(context.Background(), condition)
        if err != nil {
                log.Fatal(err)
        }

        var data []Car
        if err := cur.All(context.Background(), &amp;data); err != nil {
                log.Fatal(err)
        }

        // now we can use the data array, which contains all of the documents
        for _, car := range data {
                log.Printf("the brand is %v\n", car.Brand)
        }
}
</pre></div>
<p class="maodian"><a name="_lab2_3_1"></a></p><h3>查找符合条件的多个文档</h3>
<p>如果我们想返回<code>brand</code>为<code>Toyota</code>,那么我们可以将<code>condition</code>变量更改为</p>
<div class="jb51code"><pre class="brush:go;">condition := bson.M{
    "brand": "Toyota"
}
</pre></div>
<p class="maodian"><a name="_lab2_3_2"></a></p><h3>在查找操作中使用Projection</h3>
<p>如果要在<code>Find()</code>方法中使用<code>Projection</code>,我们可以使用<code>mongo.Options</code>参数。</p>
<p>假设我们想返回 2 个字段</p>
<ol><li>返回汽车的品牌<code>brand</code>;</li><li>返回一个布尔字段<code>isNew</code>来检查汽车是否是新的(1. 如果汽车的生产年份是 2022 年,那么它是新的; 2. 否则,它就旧了。)。</li></ol>
<p>使用<a href="https://pkg.go.dev/go.mongodb.org/mongo-driver/mongo/options" rel="external nofollow"   target="_blank">SetProjection()</a>方法来设置<code>Projection</code>字段的值:</p>
<div class="jb51code"><pre class="brush:go;">var opts = options.Find().SetProjection(
                bson.M{
                        "brand": 1,
                        "isNew": bson.M{
                                "$cond": bson.M{
                                        "if": bson.M{"$gte": bson.A{"$year", 2022}},
                                        "then": true,
                                        "else": false},
                        },
                })
cur, err := db.Collection("cars").Find(context.Background(), bson.M{}, opts)
</pre></div>
<p class="maodian"><a name="_label4"></a></p><h2>使用 Golang 更新 MongoDB 中的单个文档</h2>
<p>要更新单个文档,我们应该使用<code>FindOneAndUpdate()</code>或<code>UpdateOne()</code>操作。在本文中,我们将使用<code>FindOneAndUpdate()</code>方法来进行操作。</p>
<div class="jb51code"><pre class="brush:go;">package main

import (
        "context"
        "log"
        "time"

        "go.mongodb.org/mongo-driver/bson"
        "go.mongodb.org/mongo-driver/mongo"
        "go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        defer cancel()

        client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
        if err != nil {
                log.Fatal(err)
        }

        db := client.Database("testdb")

        filter := bson.M{
                "brand": "Toyota",
                "model": "Corolla",
        }

        update := bson.M{
                "year": 2022,
        }

        res := db.Collection("cars").FindOneAndUpdate(context.Background(), filter, update)

        if res.Err() != nil {
                log.Fatal(err)
        }

        // operation successful
}
</pre></div>
<p class="maodian"><a name="_lab2_4_3"></a></p><h3>如何在 MongoDB 中返回更新的文档?</h3>
<p>我们可以使用<code>mongo.Options</code>包来实现这一点。我们应该将返回文档的选项<code>SetReturnDocument</code>设置为<code>after</code>。</p>
<div class="jb51code"><pre class="brush:go;">opts := options.FindOneAndUpdate().SetReturnDocument(options.After)

res := db.Collection("cars").FindOneAndUpdate(context.Background(), filter, update, opts)

// we can use the updated car document
var updatedData Car

if err := res.Decode(&amp;updatedData); err != nil {
        log.Fatal(err)
}
</pre></div>
<p class="maodian"><a name="_label5"></a></p><h2>使用 Golang 从 MongoDB 中删除文档</h2>
<p>要删除文档,我们可以使用<code>*Collection</code>对象的<code>DeleteOne()</code>方法。</p>
<p>要删除多个文档,我们可以使用<code>*Collection</code>对象的<code>DeleteMany()</code>方法。</p>
<div class="jb51code"><pre class="brush:go;">package main

import (
        "context"
        "log"
        "time"

        "go.mongodb.org/mongo-driver/bson"
        "go.mongodb.org/mongo-driver/mongo"
        "go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
        ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
        defer cancel()

        client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017"))
        if err != nil {
                log.Fatal(err)
        }

        db := client.Database("testdb")

        filter := bson.M{
                "brand": "Toyota",
                "model": "Corolla",
        }

        // for single document
        res, err := db.Collection("cars").DeleteMany(context.Background(), filter)

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

        // 1 document is deleted.
        log.Printf("%v document is deleted", res.DeletedCount)
}
</pre></div>
<p class="maodian"><a name="_label6"></a></p><h2>原文地址</h2>
<p><a href="https://ocakhasan.github.io/golang-mongodb-query-examples/" rel="external nofollow"   target="_blank">MongoDB &amp; Golang Query Examples - Cheat Sheet</a></p>
頁: [1]
查看完整版本: Golang查询MongoDB的实现步骤