0
votes

Being new to Google Cloud Datastore I would like to make sure that I am on a right track.

What I need:

  • many-to-many relationship
  • the relationship itself has to hold data describing the relation
  • strong consistency is required both ways:
    • from user entity to all the data entities that this user has permissions to
    • from data entity to all the users that have permission to it

This is what I came up with:

@Entity
public class User {
    @Id String userId;
}

@Entity
public class PermissionIndex {
    @Id long id;
    @Parent Key<User> user;
    List<Ref<Permission>> permissions;
}

@Entity
public class Permission {
    @Id long id;
    boolean writePermission;
    boolean managePermission;
    @Load Ref<Data> data; //So that Data entities can be retrieved with strong
                          //consistency after looking up Permission entities
                          //for a specific User entity
    @Load Ref<User> user; //So that User entities can be retrieved with strong
                          //consistency after looking up Permission entities
                          //for a specific Data entity
}

@Entity 
public class DataIndex {
    @Id long id;
    @Parent Key<Data> data;
    List<Ref<Permission>> permissions;
}

@Enti.
public class Data {
    @Id String dataId;
    @Id String actualData;
}

If I understand right with this implementation the only way to filter Data Entities of a specific user is to get all Permission entities and filter Data entities in memory, am I right?

Is there a better way to implement it still fulfilling the requirements?

UPDATE:

In my understanding this implementation will allow me to implement logic that will retrieve data assuring strong consistency (having user id - ancestor query to retrieve all Permission entities and then using get_by_key to retrieve the Data entities).

I am wondering if I should approach it in a different way - since I do not have a lot of expierience with datastore/objectify.

2
I wonder why this question was downvoted. Please leave a comment explaining why you think it is not worth answering or how I can improve it. - gswierczynski

2 Answers

3
votes

There's an important conceptual misunderstanding inherent to the question: Relationships are not strongly or eventually consistent. Queries are.

If you perform a get-by-key operation, the result will be strongly consistent. If you perform a non-ancestor filter query, the result will eventually consistent. Rephrasing this:

If you navigate your object graph using get-by-key operations, you will see strong consistency. If you navigate your object graph using non-ancestor query filters, you will see eventual consistency.

If you need strong consistency, structure your data so that your queries can be satisfied with get-by-key operations or with ancestor queries.

1
votes

Your logic seems sound... but for a relational database.

This kind of logic doesn't hold true in the HRD that is the datastore. There are obviously ways to go around this, and you have figured them out with the way you described.

For consistency, your only chance is to use ancestor queries. The datastore is eventually consistent, only with "get_by_key" or with an ancestor query can you "force" consistency.

If you want something closer to SQL, maybe consider cloud GQL?