app engineのエンティティグループ

エンティティグループはリレーションではない

祖先とか親とか子とかいう単語が出てくるので誤解しがちだけど、エンティティグループは、1:多のようなリレーションを表現するものではない。
トランザクションによりACID特性を保障したいときに設定するもの。
リレーションはkeyをコレクションで持ったり、Slim3のModelRefなどを使って表現する。

従来のリレーション(1:1、1:多とか、到達性とか)とは本来直交する概念です*2。
Entity Groupの意味ですが、同じEntity Groupに所属するEntity群の間でのみ、トランザクションが可能になります。
Entity Groupとその簡単な構成法 - Grな日々(uehajの日記)

エンティティグループの構成は一通りではない

Person(1)をルートとして、Person(2)とPerson(3)をひとつのエンティティグループに設定する場合、Person(1)/Person(2)/Person(3)とすることもできるし、Person(1)/Person(2)、Person(1)/Person(3)とすることもできる。
両者はAncestorQueryによる取得の際に結果が異なってくる。

パスの各キーによるAncestor Queryの結果は下記のようになる。(Slim3の場合)

		// /grandParent/parent/child としてエンティティグループを構成
		Slim3Model grandParent = new Slim3Model();
		Slim3Model parent = new Slim3Model();
		Slim3Model child = new Slim3Model();
		Key grandParentKey = Datastore.put(grandParent);
		Key parentKey = Datastore.allocateId(grandParentKey, meta);
		parent.setKey(parentKey);
		Key childKey = Datastore.allocateId(parentKey, meta);
		child.setKey(childKey);
		Datastore.put(parent, child);
		
		// grandParentによるAncestor Queryはparentとchildも取得
		List<Entity> list1 = Datastore.query(grandParentKey).asList();
		assertThat(list1.size(), is(equalTo(3)));
		// parentによるAncestor QueryはgrandParentは取得されない
		List<Entity> list2 = Datastore.query(parentKey).asList();
		assertThat(list2.size(), is(equalTo(2)));
		// childによるAncestor Queryはchildのみ取得
		List<Entity> list3 = Datastore.query(childKey).asList();
		assertThat(list3.size(), is(equalTo(1)));

**エンティティグループは分散しない
エンティティグループに属するエンティティは同一サーバ上に保存される(=分散しない)ため、アクセスはスケールアウトしない。

「Entity Groupを構成する」ということの、Datastoreレベルから見た具体的な意味は、Entityに「Ancesor情報つきのKey」を持たせるということです。
Entity Groupとその簡単な構成法 - Grな日々(uehajの日記)

例:1つのDepartmentと1000のEmployeeがある場合:両者を同じエンティティグループとすると、1つのDepartmentに属する1000のEmployeeのうち、いずれか1つのEmployeeしか同時にトランザクションを実行できない(他はエラーとなりリトライが必要となる)
トランザクションとエンティティグループ - スティルハウスの書庫