努力将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"}

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"`
}{}

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.

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.