Golang:如何判断MongoDB的collection.Find未查询到任何文档?
判断MongoDB Find游标是否为空的高效方法
你已经注意到FindOne在无匹配文档时会返回ErrNoDocuments,但Find仅在查询过程出错时返回错误,空游标不会触发该错误。要无需加载所有文档就能判断游标是否为空,可以直接利用游标自身的方法:
- 核心思路:通过
Next()方法尝试读取第一个文档,结合Err()方法区分“无文档”和“查询错误”两种情况 - 具体步骤:
- 执行
Find()获取游标后,先调用cursor.Next(ctx) - 若
Next()返回false:- 调用
cursor.Err(),若返回nil则说明游标为空(无匹配文档) - 若返回非
nil值,则是查询过程中出现了错误
- 调用
- 如果需要继续遍历所有文档,可调用
cursor.Rewind(ctx)重置游标到初始位置,再正常遍历
- 执行
代码示例
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" ) func main() { ctx := context.TODO() client, err := mongo.Connect(ctx, options.Client().ApplyURI("mongodb://localhost:27017")) if err != nil { log.Fatal(err) } defer client.Disconnect(ctx) coll := client.Database("testdb").Collection("testcoll") // 执行Find查询 cursor, err := coll.Find(ctx, bson.M{"status": "inactive"}) if err != nil { log.Fatal("Find query failed:", err) } defer cursor.Close(ctx) // 判断游标是否为空 hasFirstDoc := cursor.Next(ctx) if !hasFirstDoc { if cursor.Err() != nil { log.Fatal("Cursor iteration error:", cursor.Err()) } fmt.Println("No matching documents found") return } // 重置游标以遍历所有文档(如果需要) if err := cursor.Rewind(ctx); err != nil { log.Fatal("Failed to rewind cursor:", err) } // 正常遍历所有文档 var result bson.M for cursor.Next(ctx) { if err := cursor.Decode(&result); err != nil { log.Fatal("Failed to decode document:", err) } fmt.Printf("Found document: %v\n", result) } // 检查遍历过程中是否有错误 if err := cursor.Err(); err != nil { log.Fatal("Cursor iteration error:", err) } }
注意事项
- 这种方式仅读取第一个文档的元数据,无需加载所有文档到内存,性能高效
- 调用
Rewind()前需确保游标未关闭,且处于有效状态 - 务必通过
defer cursor.Close(ctx)确保游标最终关闭,避免资源泄漏
内容的提问来源于stack exchange,提问作者Mari
相关产品推荐
相关产品推荐

