我正在尝试使用Golang为Google的数据存储区中的单个属性保存多个值。
我有一段int64,我希望能够存储和检索。从文档中我可以看到通过实现PropertyLoadSaver {}接口支持这一点。但我似乎无法提出正确的实施方案。
基本上,这就是我想要完成的事情:
type Post struct {
Title string
UpVotes []int64 `json:"-" xml:"-" datastore:",multiple"`
DownVotes []int64 `json:"-" xml:"-" datastore:",multiple"`
}
c := appengine.NewContext(r)
p := &Post{
Title: "name"
UpVotes: []int64{23, 45, 67, 89, 10}
DownVotes: []int64{90, 87, 65, 43, 21, 123}
}
k := datastore.NewIncompleteKey(c, "Post", nil)
err := datastore.Put(c, k, p)
但没有“数据存储:无效的实体类型”错误。
答案 0 :(得分:3)
默认情况下,AppEngine支持多值属性,您无需执行任何特殊操作即可使用它。您不需要实现PropertyLoadSaver
接口,也不需要任何特殊的标记值。
如果struct字段是切片类型,它将自动成为多值属性。此代码有效:
type Post struct {
Title string
UpVotes []int64
DownVotes []int64
}
c := appengine.NewContext(r)
p := &Post{
Title: "name",
UpVotes: []int64{23, 45, 67, 89, 10},
DownVotes: []int64{90, 87, 65, 43, 21, 123},
}
k := datastore.NewIncompleteKey(c, "Post", nil)
key, err := datastore.Put(c, k, p)
c.Infof("Result: key: %v, err: %v", key, err)
当然,如果您需要,可以为json和xml指定标记值:
type Post struct {
Title string
UpVotes []int64 `json:"-" xml:"-"`
DownVotes []int64 `json:"-" xml:"-"`
}
备注:强>
但请注意,如果属性已编入索引,则多值属性不适合存储大量值。这样做需要许多索引(许多写入)来存储和修改实体,并且可能会达到实体的索引限制(有关详细信息,请参阅Index limits and Exploding indexes)。
因此,例如,您不能使用多值属性为Post
存储数百个上下投票。为此,您应该将投票存储为链接到Post
的单独/不同实体,例如由Key
的{{1}}或最好只是Post
。
答案 1 :(得分:-1)
您的程序语法错误。
您确定要运行您认为正在运行的代码吗?例如,您的Post
没有必要的逗号来分隔键/值对。
go fmt
应报告语法错误。
此外,datastore.Put()
返回多个值(键和错误),代码只需要一个值。 此时应该收到编译时错误。
首先纠正这些问题:当程序无法编译时,没有必要追逐幻象语义错误。这是一个程序版本,不会引发编译时错误。
package hello
import (
"appengine"
"appengine/datastore"
"fmt"
"net/http"
)
type Post struct {
Title string
UpVotes []int64 `json:"-" xml:"-" datastore:",multiple"`
DownVotes []int64 `json:"-" xml:"-" datastore:",multiple"`
}
func init() {
http.HandleFunc("/", handler)
}
func handler(w http.ResponseWriter, r *http.Request) {
c := appengine.NewContext(r)
p := &Post{
Title: "name",
UpVotes: []int64{23, 45, 67, 89, 10},
DownVotes: []int64{90, 87, 65, 43, 21, 123},
}
k := datastore.NewIncompleteKey(c, "Post", nil)
key, err := datastore.Put(c, k, p)
fmt.Fprintln(w, "hello world")
fmt.Fprintln(w, key)
fmt.Fprintln(w, err)
}