开发者

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

开发者 https://www.devze.com 2023-03-08 02:54 出处:网络
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

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?

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

type Vote struct {
    User string
    Score int
}


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:

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:

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 {
    // handle the error
}

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

votes := make([]Vote, 0, 10)
if _, err := vq.GetAll(c, &votes); err != nil {
    // handle the error
}


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), &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
}
0

精彩评论

暂无评论...
验证码 换一张
取 消