我正在尝试使用Golang插入MongoDB,其中一个字段将包含动态数据。就我而言,它将通过gRPC来自其他服务,但我将示例简化为:
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的任何值。
您可以解决此问题的一种方法是使用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)
Data
声明为string
而不是map[string]interface{}
来存储原始JSON数据>