How to create one to many relationship into Google Cloud Datastore in Ruby

318 views
Skip to first unread message

Dimu Designs via StackOverflow

unread,
Apr 26, 2017, 11:18:09 PM4/26/17
to gcd-stac...@googlegroups.com

I concur with Renato. You essentially have a many-to-many scenario. An Author can write several Books and conversely Books can have multiple Authors.

Unfortunately there is no explicit mechanism for many-to-many relationships in Google Datastore. But you can still structure your entities to model the relationship.

For example, instead of using a hierarchical model via ancestor paths, add an array to your Book entity that store keys that reference Author entities which might look something like this:

book_key = datastore.key "Book"

author_key1 = datastore.key "Author", "john"
author_key2 = datastore.key "Author", "jane"

author_entity1 = datastore.entity author_key1 do |t|
  t["name"] = "Doe, John"
end

author_entity2 = datastore.entity author_key2 do |t|
  t["name"] = "Doe, Jane"
end

datastore.save(author_entity1, author_entity2)

And the array property on the Book entity would look something like this:

book_entity = datastore.entity book_key do |t|
  t["authors"] = [author_key1, author_key2]
end

If you want to know all the books associated with author John Doe in your database all you need do is query the "authors" array property:

query = Google::Cloud::Datastore::Query.new
query.kind("Book").
  where("authors", "=", datastore.key("Author","john"))

books_by_john = datastore.run query

Notice that I could have also gone the other way and created an array of Book keys on Author entities. But had I gone that route and tried to model a prolific Author like say Stephen King...well that Author entity would end up being pretty bloated, so you have to be selective as to which side of the relationship you add the array and try to go for the entities less likely to have bloat.



Please DO NOT REPLY directly to this email but go to StackOverflow:
http://stackoverflow.com/questions/43212453/how-to-create-one-to-many-relationship-into-google-cloud-datastore-in-ruby/43648024#43648024

Dimu Designs via StackOverflow

unread,
Apr 28, 2017, 3:51:07 PM4/28/17
to gcd-stac...@googlegroups.com

I concur with Renato. You essentially have a many-to-many scenario. An Author can write several Books and conversely Books can have multiple Authors.

Unfortunately there is no explicit mechanism for many-to-many relationships in Google Datastore. But you can still structure your entities to model the relationship.

For example, instead of using a hierarchical model via ancestor paths, add an array to your Book entity that store keys that reference Author entities which might look something like this:

book_key = datastore.key "Book"

author_key1 = datastore.key "Author", "john"
author_key2 = datastore.key "Author", "jane"

author_entity1 = datastore.entity author_key1 do |t|
  t["name"] = "Doe, John"
end

author_entity2 = datastore.entity author_key2 do |t|
  t["name"] = "Doe, Jane"
end

datastore.save(author_entity1, author_entity2)

And the array property on the Book entity would look something like this:

book_entity = datastore.entity book_key do |t|
  t["authors"] = [author_key1, author_key2]
end

If you want to know all the books associated with author John Doe in your database all you need do is query the "authors" array property:

query = Google::Cloud::Datastore::Query.new
query.kind("Book").
  where("authors", "=", datastore.key("Author","john"))

books_by_john = datastore.run query

Notice that I could have also gone the other way and created an array of Book keys on Author entities. But had I gone that route and tried to model a prolific Author like say Stephen King...well that Author entity would end up being pretty bloated with key references to Book entities, so you have to be selective as to which side of the relationship you add the array and try to go for the entities less likely to have bloat.

Reply all
Reply to author
Forward
0 new messages