Google App Engine で Objectify を使用してオブジェクト間に多対多の関係を作成する適切な方法に関するドキュメントが見つかりません。
誰でもこれを行う方法を説明できますか? このために新しい「結合」クラスを作成する必要がありますか? どのくらい効率的になりますか?
Google App Engine で Objectify を使用してオブジェクト間に多対多の関係を作成する適切な方法に関するドキュメントが見つかりません。
誰でもこれを行う方法を説明できますか? このために新しい「結合」クラスを作成する必要がありますか? どのくらい効率的になりますか?
Objectify 4.0 でこのアプローチを使用して解決しました:
@Entity
@Index
public class Module {
@Id
private Long id;
private String name;
@Load
private List<Ref<Template>> templates;
public List<Template> getTemplates() {
List<Template> templates = new ArrayList<Template>();
for (Ref<Template> temp : this.templates) {
templates.add(temp.get());
}
return templates;
}
public void setTemplates(List<Template> templatesParm) {
List<Ref<Template>> templates = new ArrayList<Ref<Template>>();
for (Template temp : templatesParm) {
templates.add(Ref.create(temp));
}
this.templates = templates;
}
どのような種類のクエリをサポートする必要がありますか?
最も簡単な解決策は次のとおりです。
@Entity
public class StoredObject {
@Id
private Long id;
private List<Long> relatedIds;
}
次に、 を指定するStoredObjectと、 を呼び出しobjectify.get(StoredObject.class, storedObject.getRelatedIds())て、関連するすべての ID を取得できます。
自分のアプリでいくつかのクエリを高速化するために、いくつかの結合クラスを作成しました。費用は書き込み時に発生します (結合を維持する必要があります) が、読み取り時は連続した結果を伴う単一のインデックス スキャンです!
これは、Objectify で多対多の関係をマッピングする最善の方法ではありません。最良の方法は、関係をマップするエンティティを作成することです。たとえば、2 つのオブジェクト A と B があり、それらが特定の方法で関連付けられているとします。次のようなクラスを作成できます。
Class Link{
Key<?> master;
key<?> slave;
public Link(){
}
public setLink(Entity master, Entity slave){
//initialize
}
}
次に、リンク エンティティを作成して関係をモデル化できます。これにより、1対1または多対多の関係が自動的にマッピングされます
1 対多について少し考えてみましょう。オブジェクト A にオブジェクト B を「多く」持たせたい場合は、次の 2 つの方法しかありません。
リレーショナルな方法: 各 B が A を指すようにします。A0 があり、それに関連するすべての B が必要な場合は、指定された A0 を指す B を照会するだけです。
NoSQL / ObjectStore の方法: B へのポインター (キー) のリストを保持するフィールドを A に持たせます。この方法では、B を特定の順序にすることもできることに注意してください (GAE/Java のドキュメントでは逆になっていますが)。
どちらが最適かによって異なります。ObjectStore の方法は、オブジェクトのサイズによって制限されます。リレーショナルな方法は、A とすべての B が同じエンティティ グループにあり、トランザクションで祖先クエリを実行しない限り (またはトランザクションに含まれていなくても)、取得が保証されるという微妙な問題の影響を受けます。その A を指すすべての B。ただし、A と B が複数のエンティティ グループにまたがる場合、クエリの述語を満たさない B を取得するか、次の条件を満たす B を見逃す可能性があります (可能性は低いですが) 。 ://developers.google.com/appengine/articles/transaction_isolation
(現在は標準の) 高レプリケーション データストアでは、トランザクションは通常、コミットが返されてから数百ミリ秒以内に完全に適用されます。ただし、完全に適用されていない場合でも、後続の読み取り、書き込み、および先祖のクエリには、コミットの結果が常に反映されます。これらの操作は、未処理の変更を実行前に適用するためです。ただし、複数のエンティティ グループにまたがるクエリは、実行前に未解決の変更があるかどうかを判断できず、古い結果または部分的に適用された結果を返す可能性があります。
さて、多対多について:宇宙でトイレに行くことを説明した話を読んだことがあります。宇宙船の内外とトイレに行く2種類の4つの組み合わせがありました。(宇宙服を着て)船の外にいることと固体を排除することの最後の組み合わせについては、唯一の答えは「優雅な方法はありません」でした(記事のタイトルでもあります):http://settlement.arc.nasa .gov/CoEvolutionBook/SPACE.HTML#There Ain't No Graceful Way ... そしてそれは、GAE における多対多の関係に対する答えでもあります。結合クラスを使用してそれらを構築でき、結合の各側はクエリまたはキーのリストで実装できます。