Вставьте документ в mongodb с одним полем, имеющим структуру Dynami c - PullRequest
0 голосов
/ 02 марта 2020

Я пытаюсь вставить в MongoDB с Go, где одно поле будет содержать данные c. В моем случае это будет другой сервис через gRP C, но я упростил пример до этого:

package main

import (
    "context"
    "fmt"
    _struct "github.com/golang/protobuf/ptypes/struct"
    "go.mongodb.org/mongo-driver/bson/primitive"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
    "log"
)

type siteItem struct {
    ID   primitive.ObjectID `bson:"_id,omitempty"`
    Name string             `bson:"name"`

    // Data string     `bson:"data"`
    Data *_struct.Value `bson:"data"`
}

func main() {
    client, _ := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
    client.Connect(context.TODO())
    collection := client.Database("site").Collection("sites")

    data := siteItem{
        Name: "Test name",

        // Data: "Test data",
        Data: &_struct.Value{
            Kind: &_struct.Value_StringValue{
                StringValue: "String from struct",
            },
        },
    }

    res, err := collection.InsertOne(context.Background(), data)
    if err != nil {
        log.Fatal(err)
    }

    fmt.Println(res)
}

И я получаю ошибку: cannot transform type main.siteItem to a BSON Document: no encoder found for structpb.isValue_Kind

Если я использую string вместо *_struct.Value - работает просто отлично. Но в моем случае Data: может иметь любое значение, которое приходит от JSON.

1 Ответ

0 голосов
/ 02 марта 2020

Один из способов справиться с этим - пометить структуру тегами bson, что не всегда возможно. Я рассмотрел этот случай, используя одно из следующих действий, в зависимости от ситуации:

  • Использование map[string]interface{} и JSON маршалинг:
type Item struct {
   Data map[string]interface{} `bson:"data"`
}

...
// Writing to db
data,_:=json.Marshal(someStruct)
json.Unmarshal(data,&item.Data)
// Reading from db
data,_:=json.Marshal(item.Data)
json.Unmarshal(data,&result.Data)
  • Сохраните необработанные данные JSON, объявив Data как string вместо map[string]interface{}
...