以下是使用 MongoDB 的原子操作来实现自动增长 ID 并永久保存的方法:
package main
import (
"context"
"fmt"
"log"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
type Counter struct {
ID string `bson:"_id"`
Value int `bson:"value"`
}
func getNextID(ctx context.Context, collection *mongo.Collection) (int, error) {
update := bson.M{
"$inc": bson.M{"value": 1},
}
upsert := true
after := options.After
opt := options.FindOneAndUpdateOptions{
Upsert: &upsert,
ReturnDocument: &after,
}
var counter Counter
err := collection.FindOneAndUpdate(ctx, bson.M{"_id": "documentIdCounter"}, update, &opt).Decode(&counter)
if err!= nil {
return 0, err
}
return counter.Value, nil
}
func main() {
clientOptions := options.Client().ApplyURI("mongodb://localhost:27017")
client, err := mongo.Connect(context.TODO(), clientOptions)
if err!= nil {
log.Fatal(err)
}
defer client.Disconnect(context.TODO())
collection := client.Database("testdb").Collection("counters")
for i := 0; i < 5; i++ {
id, err := getNextID(context.TODO(), collection)
if err!= nil {
log.Fatal(err)
}
fmt.Println("Generated ID:", id)
time.Sleep(time.Second)
}
}
在这个示例中:
- 定义了一个
Counter
结构体来表示存储自动增长 ID 的文档结构。 getNextID
函数使用FindOneAndUpdate
方法来原子性地增加计数器的值,并返回新的 ID。如果计数器文档不存在,会自动创建并初始化为 1。- 在主函数中,循环调用
getNextID
函数生成多个 ID,并打印出来。
这样可以确保自动增长的 ID 永久保存在 MongoDB 中,并且每次获取的 ID 是基于上次的结果。