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(), &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(), &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(&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 & Golang Query Examples - Cheat Sheet</a></p>
頁:
[1]