App Engine数据存储:如何使用golang在属性上设置多个值?

时间:2015-04-24 23:11:55

标签: google-app-engine go google-cloud-datastore

我正在尝试使用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)

但没有“数据存储:无效的实体类型”错误。

2 个答案:

答案 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)
}