doulu8341
doulu8341
2019-02-23 01:13

努力将MongoDB singleResult对象转换为Go结构

已采纳

I tried to follow documentation here and here but had no luck.

I want to get a singleResult from FindOne on the Collection named moviesCollection and then use Decode or Unmarshal to put those values into a struct. The values in the struct JSONData are exactly the same as in each Document

I am using the official mongodb driver github.com/mongodb/mongo-go-driver

Here is an example of what I have tried:

mongoContext, cancelContext := context.WithTimeout(context.Background(), 10*time.Second)

defer cancelContext()

mongoClient, _ := mongo.Connect(mongoContext, options.Client().ApplyURI("mongodb://localhost:27017"))
moviesCollection := mongoClient.Database("Entertainment").Collection("Movies")

moviesCollection.InsertOne(mongoContext, bson.M{"_id": "Deadpool", "Path": "path/to/file"})

singleResult := moviesCollection.FindOne(mongoContext, bson.M{"_id": "Deadpool"})

if singleResult.Err() != nil {
    log.Println("Find error: ", singleResult.Err())
}

JSONData := struct {
    Path string `json:"Path"`
}{}

decodeError := singleResult.Decode(&JSONData)

if decodeError != nil {
    log.Println("Decode error: ", decodeError)
}

fmt.Println("Path: ", JSONData.Path)

However no errors are produced and JSON.Path produces and empty string.

I have also tried using bson.D{{"_id", "Deadpool"}} instead of bson.M{"_id": "Deadpool"}

I can confirm that JSON.Path is not empty string as I have checked the database natively using MongoDB Compass. The entry contains the following:

{"_id":"Deadpool","Path":"path/to/file"}
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享
  • 邀请回答

3条回答

  • doumizhi0809 doumizhi0809 2年前

    Internally, MongoDB uses bson. Change your struct as below should work.

    From

    JSONData := struct {
        Path string `json:"Path"`
    }{}
    

    to

    JSONData := struct {
        Path string `bson:"Path"`
    }{}
    
    点赞 评论 复制链接分享
  • dousong2023 dousong2023 2年前

    Hey so as simagix mentioned you should be able to change your tag from JSON to bson:

    `bson:"Path"`
    

    Another option, incase you need to obtain a more generic result is to pass it a D object like so:

    JSONData := &bson.D{}
    decodeError := singleResult.Decode(JSONData)
    

    You can then obtain all the information through a map using the JSON.Data.Map function.

    点赞 评论 复制链接分享
  • dsxml2169 dsxml2169 2年前

    If you are using mongo-go-driver >= v.0.1.0 then, taking a look to the go-doc it looks pretty straightforward:

    filter := bson.D{{"hello", "world"}}
    err := collection.FindOne(context.Background(), filter).Decode(&result)
    if err != nil { return err }
    // do something with result...
    

    So, what you need is:

    package main
    
    import (
        "context"
    
        "github.com/mongodb/mongo-go-driver/bson"
        "github.com/mongodb/mongo-go-driver/mongo
    )
    
    func main() {
    
        ctx := context.Background()
    
        client, err := mongo.NewClient("mongodb://localhost:27017")
        if err != nil {
           ...
        }
    
        if err := client.Connect(ctx); err != nil {
            ...
        }
    
        defer client.Disconnect(ctx)
    
        collection := client.Database("myDb").Collection("movies")
    
        filter := bson.D{{"_id", "sometitle"}}
    
        var result JSONData
    
        err := collection.FindOne(ctx, filter).Decode(&result)
        if err != nil { 
            ...
        }
    
        // Do Something cool here
    
    }
    

    I see you are using Title to filter the doc. Pay attention.

    点赞 评论 复制链接分享

相关推荐