Golang GraphQL MongoDB 努力从数据库中获取日期和 ID

Posted

技术标签:

【中文标题】Golang GraphQL MongoDB 努力从数据库中获取日期和 ID【英文标题】:Golang GraphQL MongoDB Struggling to get date and id out of the Database 【发布时间】:2020-08-14 02:32:49 【问题描述】:

我是 Golang 和 Graphql 的新手,所以我可能搞砸了很多配置,但我很难使用我创建的 GraphQL API 从我的数据库中获取返回值。每当我使用我在 Golang 中创建的 GraphQL API 查询我的数据库时,它都会抛出错误 cannot decode UTC datetime into a string type 并努力获取 id。

这是我的 GrapqhQL 架构:

    type User 
    _id:  ID!
    username: String!
    passwordHash: String!
    email: String!
    userInfo: userStats
    profileStats: profileInfo




type userStats 
    firstName: String
    lastName: String
    birthday: String
    dateCreated: String!
    nativeLanguage: String
    currentlyLearning: String
    location: Location


type Location 
    city: String
    state: String
    zipcode: Int
    country: String


type profileInfo 
    level: Int
    xp: Int
    xpTillNextLevel: Int
    posts: Int


input NewUser 
    id: ID!
    username: String!
    passwordHash: String!
    email: String!
    userStats: String
    profileInfo: String


type Mutation 
    createUser(input: NewUser!): User!


type Query 
    users: [User!]!
    user(id: ID!): User!

这是我在提供查询时执行的代码:

func (u *UserRepo) GetUsers() ([]*model.User, error) 

    var users []*model.User

    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    defer cancel()

    usersCollection := u.DB.Collection(u.KEYS["collection"].(string))

    cursor, err := usersCollection.Find(ctx, bson.M)
    if err != nil 
        fmt.Println(err)
        return nil, err
    

    if err = cursor.All(ctx, &users); err != nil 
        fmt.Println(err)
        return nil, err
    
    fmt.Println(users[0])

    return users, nil


func (u *UserRepo) GetUserById(id string) (*model.User, error) 

    var user model.User

    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    defer cancel()

    usersCollection := u.DB.Collection(u.KEYS["collection"].(string))

    userID, err := primitive.ObjectIDFromHex(id)
    if err != nil 
        fmt.Println("Invalid ObjectID")
    

    err = usersCollection.FindOne(ctx, bson.M"_id": userID).Decode(&user)
    if err != nil 
        fmt.Println("error retrieving user userid : " + id)
        fmt.Printf("error: %d", err)
        //return nil, err
    

    fmt.Println(err)

    fmt.Println(user)

    return &user, nil


If I uncomment the return nil,err on the bottom query for selecting one user by the id, it will just return the error of the date and no information so I am leaving it commented out for testing purposes.

我的查询和结果

query:
query getUsers 
  user(id: "5ea75c4c67f9266c89dfb659") 
    _id
    username
    email
    passwordHash
    userInfo
      lastName
      dateCreated
      location
        state
      
    
    profileStats
      level
    
  


result: 

  "data": 
    "user": 
      "_id": "",
      "username": "Aerith",
      "email": "Aerith@LanguageLearning.com",
      "passwordHash": "testingpassword",
      "userInfo": 
        "lastName": "Gainsborough",
        "dateCreated": "",
        "location": null
      ,
      "profileStats": null
    
  

这是我为在 MongoDB 数据库中测试而制作的示例数据集

db.users.findOne(_id: ObjectId("5ea75c4c67f9266c89dfb659"))

    "_id" : ObjectId("5ea75c4c67f9266c89dfb659"),
    "username" : "Aerith",
    "passwordHash" : "testingpassword",
    "email" : "Aerith@LanguageLearning.com",
    "userInfo" : 
        "firstName" : "Aerith",
        "lastName" : "Gainsborough",
        "birthday" : ISODate("1985-02-07T00:00:00Z"),
        "dateCreated" : ISODate("2020-04-27T22:27:24.650Z"),
        "nativeLanguage" : "English",
        "currentlyLearning" : "Japanese",
        "location" : 
            "city" : "Sector 5",
            "state" : "Midgar",
            "zipcode" : 77777,
            "country" : "FF7"
        
    ,
    "profileStats" : 
        "level" : 1,
        "xp" : 0,
        "xpTillNextLevel" : 1000,
        "comments" : 0,
        "posts" : 0
    

此外,位置和个人资料统计信息也只是空空如也,我不知道为什么。 很抱歉代码量很长,但我正在努力提供尽可能多的信息来帮助找到答案。希望这会有所帮助,并且我可以就如何解决此问题获得一些保证。提前感谢您的所有帮助。

编辑:在 userStats 类型中进行了一些测试后,我可以获得 firstName 和 lastName 但它失败并且光标在到达生日时由于数据错误而崩溃。这就是为什么生日下一切都是空的。所以问题是我如何解码 mongo 日期,以便我可以放入 userStates。我很想把所有东西都拉成 bson 并将其转换为正确的模型结构,但这似乎需要做很多额外的工作,我真的不想诉诸于此。

【问题讨论】:

【参考方案1】:

一些 BSON 类型没有与 Go 原始类型的直接映射,因此您需要具有自定义解组的类型,无论是您自己制作的还是已经在 bson/primitive 包上完成的

尝试以这种方式定义您的用户统计结构:

import "go.mongodb.org/mongo-driver/mongo/primitive"

type UserStats 
    ...
    BirthDay primitive.DateTime `bson:"birthday"`
    //OR BirthDay primitive.Timestamp `bson:"birthday"`
    ...

https://pkg.go.dev/go.mongodb.org/mongo-driver/bson@v1.3.3?tab=doc#hdr-Native_Go_Types

https://pkg.go.dev/go.mongodb.org/mongo-driver/bson/primitive

https://pkg.go.dev/go.mongodb.org/mongo-driver/bson/primitive?tab=doc#DateTime

https://pkg.go.dev/go.mongodb.org/mongo-driver/bson/primitive?tab=doc#Timestamp

【讨论】:

以上是关于Golang GraphQL MongoDB 努力从数据库中获取日期和 ID的主要内容,如果未能解决你的问题,请参考以下文章

使用 golang 和 mgo,如何在 MongoDB 中搜索一系列值?

将 GraphQL 与 MongoDB 连接时为空

Vue Apollo:变量未添加到 graphql 查询,或者我在后端没有正确接受它们(Golang)

.NET Core 3.1 + GraphQL + MongoDB

GraphQL 和 MongoDB 游标

GraphQL 用例:使用 Golang 和 PostgreSQL 构建一个博客引擎 API