Search code examples
mongodbgostructmongo-go

Using MongoDB Projection


I have the following structure in my database:

{
  "_id": {
    "$oid": "5fc4fc68fcd604bac9f61f71"
  },
  "init": {
    "fullname": "Besikta Anibula",
    "parts": [
      "Besikta",
      "Anibula"
    ],
    "alt": "Besikta Ani."
  },
  "industry": "E-Commerce"
}

I´m trying to just access the init object and write the results to a structured variable in Go:

var InputData struct {
    Fullname    string  `bson:"fullname" json:"fullname"`
    Parts       []string`bson:"parts" json:"parts"`
    Alt         string  `bson:"alt" json:"alt"`
}

collectionRESULTS.FindOne(ctx, options.FindOne().SetProjection(bson.M{"init": 1})).Decode(&InputData)
js, _ := json.Marshal(InputData)
fmt.Fprint(writer, string(js))

But the result is empty:

{"fullname":"","parts":null,"alt":""}

It is working when not using a projection like:

var InputData struct {
    Ident   primitive.ObjectID `bson:"_id" json:"id"`
}

collectionRESULTS.FindOne(ctx, bson.M{}).Decode(&InputData)
js, _ := json.Marshal(InputData)
fmt.Fprint(writer, string(js))

Result as expected:

{"id":"5fc4fc68fcd604bac9f61f71"}

Solution

  • You set the projection to only retrieve the init property of the result documents, and then you try to unmarshal into a struct value that does not have any matching field for the init value, so nothing will be set in that struct value.

    You must use a value that has an init field, like this wrapper Result struct:

    type Result struct {
        Init InputData `bson:"init"`
    }
    type InputData struct {
        Fullname    string   `bson:"fullname" json:"fullname"`
        Parts       []string `bson:"parts" json:"parts"`
        Alt         string   `bson:"alt" json:"alt"`
    }
    

    Use it like this:

    var result Result
    err := collectionRESULTS.FindOne(ctx, bson.M{}, options.FindOne().
        SetProjection(bson.M{"init": 1})).Decode(&result)
    if err != nil {
        // handle error
    }