在Go语言中,我该如何在App Engine上实现一对多关系?

huangapple go评论92阅读模式
英文:

How would I implement one-to-many on App Engine in Go?

问题

在Google App Engine中,使用Go编程语言如何实现一对多关系?例如,如果我有以下结构体,如何存储多个投票与一个评论的关联?我应该在Comment结构体中使用一个Votes的键数组(切片),还是在Vote结构体中使用一个Comment的键?

<!-- language: lang-go -->

type Comment struct {
    Author  string
    Content string
    Date    datastore.Time
}

type Vote struct {
	User string
	Score int
}
英文:

How would I implement one-to-many on Google App Engine in the Go programming language?
For example, if I have the structs below, how would I store the association of many Votes to one Comment? Would I use an array (slice) of keys to Votes in the Comment struct, or one key to the Comment from the Vote struct?

<!-- language: lang-go -->

type Comment struct {
    Author  string
    Content string
    Date    datastore.Time
}

type Vote struct {
	User string
	Score int
}

答案1

得分: 18

在当前版本的Go AppEngine SDK中,允许在字段中使用的类型有以下几种:

  • 有符号整数(int、int8、int16、int32和int64)
  • 布尔类型(bool)
  • 字符串类型(string)
  • 浮点数类型(float32和float64)
  • 任何底层类型是上述预定义类型之一的类型
  • *Key
  • appengine.BlobKey
  • []byte(长度最多为1兆字节)
  • 上述任何类型的切片(长度最多为100个元素)

鉴于此,似乎有两种方法可以实现这个。一种方法是维护一个指向给定评论的Votes的键的切片。然而,这很可能会超过任何相对受欢迎的评论的100个元素限制。

另一种方法是在每个投票结构中存储对评论的“指针”,如下所示:

type Vote struct {
    User string
    Score int
    CommentKey *datastore.Key
}    

type Comment struct {
    Author  string
    Content string
    Date    datastore.Time
}

然后,当您进行查询时,需要分两步进行。首先,获取您感兴趣的评论(在这种情况下,只返回第一个评论)。其次,查询所有“指向”该评论的投票:

q := datastore.NewQuery("Comment").Limit(1)
comments := make([]Comment, 0, 1)
var err os.Error
var keys []*datastore.Key
if keys, err = q.GetAll(c, &comments); err != nil {
    // 处理错误
}

comment := comments[0]
vq := datastore.NewQuery("Vote").Filter("CommentKey=", keys[0])

votes := make([]Vote, 0, 10)
if _, err := vq.GetAll(c, &votes); err != nil {
    // 处理错误
}
英文:

The only types that are allowed for fields in the current version of the Go AppEngine SDK are as follows:

  • signed integers (int, int8, int16, int32 and int64),
  • bool,
  • string,
  • float32 and float64,
  • any type whose underlying type is one of the above predeclared types,
  • *Key,
  • appengine.BlobKey,
  • []byte (up to 1 megabyte in length),
  • slices of any of the above (up to 100 elements in length).

Given that, there appear to be two ways to do this. One is to maintain a slice of keys to point to the Votes of a given Comment. However this is likely to run up against the 100 element limit for any reasonably popular comment.

The other approach is to store a "pointer" to the comment in each vote struct like this:

<!-- language: lang-go -->

type Vote struct {
    User string
    Score int
    CommentKey *datastore.Key
}    

type Comment struct {
    Author  string
    Content string
    Date    datastore.Time
}

Then when you go to query it you need to do it in two steps. First you get the Comment you're interested in (in this case just the first one that happens to be returned). Second, you query for all the votes that "point" to that comment:

<!-- language: lang-go -->

q := datastore.NewQuery(&quot;Comment&quot;).Limit(1)
comments := make([]Comment, 0, 1)
var err os.Error
var keys []*datastore.Key
if keys, err = q.GetAll(c, &amp;comments); err != nil {
    // handle the error
}
	
comment := comments[0]
vq := datastore.NewQuery(&quot;Vote&quot;).Filter(&quot;CommentKey=&quot;, keys[0])
	
votes := make([]Vote, 0, 10)
if _, err := vq.GetAll(c, &amp;votes); err != nil {
    // handle the error
}

答案2

得分: 4

如何将投票作为评论的子项存储,使用祖先路径?我是指在存储每个新的投票结构时,将父键参数设置为指向父评论。就像这样:

key, err := datastore.Put(context, datastore.NewIncompleteKey(context, model.DB_KIND_VOTE, commentKey), &vote)
英文:

How about to store Votes as child items of Comment, using ancestor paths? I mean set parent key parameter pointing to parent Comment when you storing each new Vote struct. Something like this:

key, err := datastore.Put(context, datastore.NewIncompleteKey(context, model.DB_KIND_VOTE, commentKey), &amp;vote)

答案3

得分: -1

我还没有尝试过这个,但或许值得一试:

type Vote struct {
    User string
    Score int
}    

type Comment struct {
    Author  string
    Content string
    Date    datastore.Time
    Votes*  []Vote
}
英文:

I haven't tried this, but maybe it's worth trying:

type Vote struct {
    User string
    Score int
}    

type Comment struct {
    Author  string
    Content string
    Date    datastore.Time
    Votes*  []Vote
}

huangapple
  • 本文由 发表于 2011年5月25日 21:38:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/6125345.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定