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.
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.