Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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
}
like image 268
kristianp Avatar asked May 25 '11 13:05

kristianp


People also ask

How many App Engine applications can be created in a project?

Deployment. Let's first take a quick look into how we deploy these five applications to App Engine. In App Engine, we can create a single Application per project.

What are the two kinds of instances available in App Engine standard?

App Engine supports the following scaling types, which controls how and when instances are created: Automatic (default) Basic. Manual.

How many app engines are in a project in GCP?

Each Cloud Platform project can contain one App Engine application.

How do I add services to my App Engine?

You can add multiple services in your project by creating an app. yaml file for each service. Include the service attribute in each app. yaml file to specify the name of the service.


2 Answers

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
}
like image 158
laslowh Avatar answered Oct 11 '22 22:10

laslowh


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)
like image 44
Fedir Tsapana Avatar answered Oct 11 '22 22:10

Fedir Tsapana