Golang中MongoDB查询返回空结果的问题

Golang中MongoDB查询返回空结果的问题 大家好, 当我尝试使用以下方法登录时: https://play.golang.org/p/Sv5ZULBZMzL

收到了这个错误信息: http: panic serving 127.0.0.1:56486: mongo: no documents in result

正如你所见,我放置了一些日志。但输出中没有任何日志 (我构建了Go文件并将其放在模板文件旁边)

可以请教我如何修复这个问题吗?谢谢。

2 回复

此错误在此处有文档说明。显然,在 database.ADMIN_COLLECTION 中没有匹配 {"phone": phone, "password": password} 的记录。

我建议您记录下 database.ADMIN_COLLECTIONphonepassword 的值,然后自行查询您的 MongoDB 数据库,看看是否能找到匹配的值。

我不知道您是否这样做,但我想建议不要在数据库中以明文形式存储密码。我希望您的 password 参数是经过加密和/或哈希加盐处理的,等等。

更多关于Golang中MongoDB查询返回空结果的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


从错误信息mongo: no documents in result来看,问题在于查询没有返回任何文档。这通常发生在查询条件不匹配数据库中的任何记录时。以下是可能导致此问题的原因及解决方案:

1. 检查查询条件

确保查询条件与数据库中的数据匹配。使用FindOne时,如果没有匹配的文档,会返回此错误。

// 示例:检查查询条件
filter := bson.M{"username": username, "password": password}
var result bson.M
err := collection.FindOne(context.Background(), filter).Decode(&result)
if err != nil {
    if err == mongo.ErrNoDocuments {
        // 没有找到匹配的文档
        log.Println("No user found with provided credentials")
        return
    }
    log.Fatal(err)
}

2. 添加调试日志

在查询前后添加详细的日志,查看实际执行的查询条件:

// 添加调试日志
log.Printf("Querying with filter: %+v", filter)

var user User
err := collection.FindOne(ctx, filter).Decode(&user)
if err != nil {
    if err == mongo.ErrNoDocuments {
        log.Printf("No document found for filter: %+v", filter)
        // 返回适当的错误响应
        return
    }
    log.Printf("Database error: %v", err)
    return
}

log.Printf("Found user: %+v", user)

3. 检查数据库连接和数据

确保:

  • MongoDB服务正在运行
  • 连接到了正确的数据库和集合
  • 集合中存在符合条件的数据
// 验证集合是否存在数据
count, err := collection.CountDocuments(ctx, bson.M{})
if err != nil {
    log.Printf("Error counting documents: %v", err)
    return
}
log.Printf("Total documents in collection: %d", count)

// 查看所有用户数据(仅用于调试)
cursor, err := collection.Find(ctx, bson.M{})
if err != nil {
    log.Printf("Error finding all documents: %v", err)
    return
}
defer cursor.Close(ctx)

for cursor.Next(ctx) {
    var doc bson.M
    if err := cursor.Decode(&doc); err != nil {
        log.Printf("Error decoding document: %v", err)
        continue
    }
    log.Printf("Document in collection: %v", doc)
}

4. 处理查询结果

正确处理ErrNoDocuments错误:

func login(username, password string) error {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    
    filter := bson.M{
        "username": username,
        "password": bson.M{"$exists": true}, // 确保字段存在
    }
    
    var user User
    err := collection.FindOne(ctx, filter).Decode(&user)
    if err != nil {
        if errors.Is(err, mongo.ErrNoDocuments) {
            // 没有找到用户
            return fmt.Errorf("invalid credentials")
        }
        return fmt.Errorf("database error: %w", err)
    }
    
    // 验证密码(建议使用哈希比较)
    if !checkPasswordHash(password, user.PasswordHash) {
        return fmt.Errorf("invalid credentials")
    }
    
    return nil
}

5. 检查字段名大小写

确保查询中的字段名与数据库中的字段名完全匹配(包括大小写):

// 使用正确的字段名
filter := bson.M{
    "UserName": username,  // 注意大小写
    "Password": password,
}

6. 完整示例代码

package main

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

type User struct {
    Username string `bson:"username"`
    Password string `bson:"password"`
}

func main() {
    // 连接MongoDB
    client, err := mongo.Connect(context.Background(), 
        options.Client().ApplyURI("mongodb://localhost:27017"))
    if err != nil {
        log.Fatal(err)
    }
    
    collection := client.Database("testdb").Collection("users")
    
    // 登录函数
    err = login(collection, "testuser", "testpass")
    if err != nil {
        log.Printf("Login failed: %v", err)
    }
}

func login(collection *mongo.Collection, username, password string) error {
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    
    filter := bson.M{"username": username}
    
    log.Printf("Executing query with filter: %v", filter)
    
    var user User
    err := collection.FindOne(ctx, filter).Decode(&user)
    if err != nil {
        if err == mongo.ErrNoDocuments {
            log.Printf("User '%s' not found in database", username)
            return fmt.Errorf("user not found")
        }
        return err
    }
    
    log.Printf("Found user: %+v", user)
    
    // 验证密码
    if user.Password != password {
        return fmt.Errorf("invalid password")
    }
    
    log.Println("Login successful")
    return nil
}

主要问题很可能是查询条件不匹配数据库中的实际数据。建议先使用MongoDB Compass或mongo shell验证数据库中的实际数据,然后调整查询条件。

回到顶部