Golang GraphQL MongoDB Изо всех сил пытается получить дату и идентификатор из базы данных - PullRequest
0 голосов
/ 29 апреля 2020

Я новичок в Golang и Graphql, так что я, вероятно, испортил большую часть конфигурации, но я изо всех сил пытаюсь получить значения, возвращенные из моей базы данных, с помощью созданного мной API-интерфейса GraphQL. Всякий раз, когда я запрашиваю свою базу данных, используя GraphQL API, который я создал в Golang Он выдает ошибку, не может декодировать UT C datetime в строковый тип и пытается вывести идентификатор.

Вот моя схема 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
    }
}

Кроме того, статистика местоположения и профиля просто возвращается пустой и нулевой, и я понятия не имею, почему. Извините за большой объем кода, но я пытаюсь предоставить как можно больше информации, чтобы помочь найти ответ. Надеюсь, это поможет, и я могу получить некоторую уверенность в том, как решить эту проблему. Заранее благодарю за всю вашу помощь.

edit: после некоторого тестирования в типе userStats я могу получить firstName и lastName, но он не работает, и курсор падает из-за ошибки данных при достижении дня рождения. Вот почему все не имеет значения в день рождения. Таким образом, проблема заключается в том, как мне декодировать дату понедельника go, чтобы я мог указать пользовательские состояния. Я испытываю желание просто взять все как bson и преобразовать его в правильные структуры модели, но это похоже на большую дополнительную работу, и я действительно не хочу прибегать к этому.

1 Ответ

0 голосов
/ 07 мая 2020

Некоторые типы BSON не имеют прямого сопоставления с Go примитивными типами, поэтому вам нужны типы с настраиваемым unmarshalling, либо ваши собственные, либо уже сделанные в пакете 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

...