我想在 Google Cloud Datastore(Datastore 模式下的 Firestore)中保存一部分结构。
以电话簿和联系人为例。
type Contact struct {
Key *datastore.Key `json:"id" datastore:"__key__"`
Email string `json:"email" datastore:",noindex"`
Name string `json:"name" datastore:",noindex"`
}
type Phonebook struct {
Contacts []Contact
Title string
}
保存和加载这个结构没有问题,因为 Datastore library照顾好它。
由于我的实际代码中存在一些复杂的属性,我需要实现PropertyLoadSaver
方法。
保存 Title
属性很简单。但是我在存储联系人结构的 slice 时遇到了问题。
我尝试使用 SaveStruct
方法:
func (pb *Phonebook) Save() ([]datastore.Property, error) {
ps := []datastore.Property{
{
Name: "Title",
Value: pb.Title,
NoIndex: true,
},
}
ctt, err := datastore.SaveStruct(pb.Contacts)
if err != nil {
return nil, err
}
ps = append(ps, datastore.Property{
Name: "Contacts",
Value: ctt,
NoIndex: true,
})
return ps, nil
}
此代码编译但不工作。
错误信息是datastore: invalid entity type
显式制作 Property slice 也不起作用:
func (pb *Phonebook) Save() ([]datastore.Property, error) {
ps := []datastore.Property{
{
Name: "Title",
Value: pb.Title,
NoIndex: true,
},
}
cttProps := datastore.Property{
Name: "Contacts",
NoIndex: true,
}
if len(pb.Contacts) > 0 {
props := make([]interface{}, 0, len(pb.Contacts))
for _, contact := range pb.Contacts {
ctt, err := datastore.SaveStruct(contact)
if err != nil {
return nil, err
}
props = append(props, ctt)
}
cttProps.Value = props
}
ps = append(ps, cttProps)
return ps, nil
}
制作实体 slice 也不起作用:
func (pb *Phonebook) Save() ([]datastore.Property, error) {
ps := []datastore.Property{
{
Name: "Title",
Value: pb.Title,
NoIndex: true,
},
}
cttProps := datastore.Property{
Name: "Contacts",
NoIndex: true,
}
if len(pb.Contacts) > 0 {
values := make([]datastore.Entity, len(pb.Contacts))
props := make([]interface{}, 0, len(pb.Contacts))
for _, contact := range pb.Contacts {
ctt, err := datastore.SaveStruct(contact)
if err != nil {
return nil, err
}
values = append(values, datastore.Entity{
Properties: ctt,
})
}
for _, v := range values {
props = append(props, v)
}
cttProps.Value = props
}
ps = append(ps, cttProps)
return ps, nil
}
两者都产生了相同的错误 datastore: invalid entity type
最后我求助于使用 JSON。 Contact slice 被转换为 JSON 数组。
func (pb *Phonebook) Save() ([]datastore.Property, error) {
ps := []datastore.Property{
{
Name: "Title",
Value: pb.Title,
NoIndex: true,
},
}
var values []byte
if len(pb.Contacts) > 0 {
js, err := json.Marshal(pb.Contacts)
if err != nil {
return nil, err
}
values = js
}
ps = append(ps, datastore.Property{
Name: "Contacts",
Value: values,
NoIndex: true,
})
return ps, nil
}
除了使用 JSON 之外,还有更好的方法吗?
最佳答案
我找到了这个 document它提到 src 必须是一个结构指针。
关于go - 将一片结构保存到 Cloud Datastore(Datastore 模式下的 Firestore)中的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57577121/