Golang GraphQL MongoDB Struggling to get date and id out of the Database

喜欢而已 提交于 2021-02-11 15:40:51

问题


I am new to Golang and Graphql so I probably messed a lot of the configuration up but I am struggling to get values returned from my database using the GraphQL API I created. Whenever I query my database using the GraphQL API I created in Golang It throws the error cannot decode UTC datetime into a string type and struggles to get the id out.

Here is my GrapqhQL schema:

    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!
}

Here is my code that executes when a query is provided:

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.

my query and result

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
    }
  }
}

and here is example dataset that I made for testing in my MongoDB database

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
    }
}

Also the location and profile stats are just coming back empty and null and I have no clue why. Sorry for the long amount of code but I am trying to provide the most information possible to assist with finding the answer. Hopefully, this helps and I can get some assurance on how to fix this issue. Thank you for all your help in advance.

edit: after some testing in the userStats type I can get the firstName and lastName but it fails and the cursor crashes because of the data error when it hits birthday. This is why everything is null under birthday. So the issues is how do I decode the mongo date so I can put in the userStates. I am tempted to just pull everything as bson and convert it to correct model structs but that seems like to much extra work and I really do not want to resort to this.


回答1:


Some BSON types doesn't have direct mapping with Go primitive types, so you need types with custom unmarshalling, either your own made or already done on bson/primitive package

Try defining your user stats struct that way:

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



来源:https://stackoverflow.com/questions/61511365/golang-graphql-mongodb-struggling-to-get-date-and-id-out-of-the-database

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!