Search code examples
google-app-enginegoogle-cloud-datastoredatastore

When does it make sense to have the same parent key to entities of different kinds?


When does it make sense to have the same parent key to entities of different kinds? If you create the entities like this:

Key k1 = KeyFactory.createKey("X", "x1");
String kind_A = "A";
String kind_B = "B";
Entity e1 = new Entity(kind_A, "a1", k1);       
Entity e2 = new Entity(kind_B, "b1", k1);
        
Query q1 = new Query(k1); //{will return a1, b1}
Query q2 = new Query(kind_A, k1); // will return a1

If e1 has properties names: p1, p2, p3, and e2 has properties names: p3, p4, p5, and you create queries like this:

Query q3 = new Query(k1).addSort("p3");
Query q4 = new Query(kind_A, k1).addSort("p3");

How many indexes will be created for key k1(X, x1)?

Will there be indexes for each kind: p1_A, p2_A, p3_A, p3_B, p4_B, p5_B, plus shared indexes for each property from A and B: p1_Shared, p2_Shared, p3_Shared, p4_Shared, p5_Shared?

How the values of p3 will be compared if they are of different types, ex Long and String, or Blob and String/Long?


Solution

  • I will try to address the several questions that you exposed here.

    When does it make sense to have the same parent key to entities of different kinds?

    Data should be modeled with the kinds that are needed. If a kind has a natural parent then it makes sense to use a parent key, which allows you to query for parents without creating indexes. If two different kinds have the same natural parent, you should do this.

    How many indexes will be created for key k1(X, x1)?

    Multiple separated indexes will not be created, but the same general purpose indexes will be used for several different things. There's an implicit primary key index entry for the group <parent_key, kind, id>. For properties there's the entry <kind, property_name, property_value>. This way, Datastore can effectively search for a specific entity with its full key including the parent, it can search for entities with an specific parent, or it can search for a property's name/value when the type is known.

    Query q3 = new Query(k1).addSort("p3");

    This query is not valid. There's no index <parent_key, property_name, property_value>, and composite index are not supported without a kind. Doing so would force Datastore to search a potentially very large amount of data.

    This is explained in the documentation: "A query with no kind and no ancestor retrieves all of the entities of an application from Datastore mode. Such kindless queries cannot include filters or sort orders on property values."

    Query q4 = new Query(kind_A, k1).addSort("p3");

    This query is not valid either. there's no index <parent_key, kind, property_name, property_value>. Nonetheless, you could create a composite index on kind "A" property "p3", including ancestors.

    How the values of p3 will be compared if they are of different types?

    According to the documentation, the properties will be ordered according to their type and then sorted according to their values.