我在谷歌的AppEngine上使用Objectify。 我有以下实体模型:
@Entity
public class ChallengeEntity {
@Id
private Long id;
@Index
public List<ChallengeParticipant> participants;
}
参与者(不是实体......应该是一个吗?)
public class ChallengeParticipant {
@Load
public Ref<UserEntity> user;
// ... participant-specific attributes
}
用户实体:
@Entity
public class UserEntity {
@Id
Long id;
@Index
public String email = "";
}
现在我如何找到给定用户电子邮件的所有挑战? 一些事情:
ofy().load().type(ChallengeEntity.class).filter("participants.user.email", "test@local.foo")
我愿意让我的实体模型适应GAE的需求......我怎样才能有效地支持 这个查询并保持一个好的模型?
非常感谢
答案 0 :(得分:1)
假设电子邮件对用户来说是唯一的,我会将ChallengeParticipant
作为单独的实体保留,并与ChallangeEntity
保持双向关系:
public class ChallengeParticipant {
@Id
String email; // must be able to uniquely identify a user.
List<Ref<ChallengeEntity>> challenges;
// ... participant-specific attributes
}
ChallengeEntity将按原样存在,但没有任何@Index
@Entity
public class ChallengeEntity {
@Id
private Long id;
public List<Ref<ChallengeParticipant>> participants;
}
如果要为挑战添加新参与者,请在一个事务中更新两个实体(参与者和挑战)。由于没有涉及索引,您将始终获得一致的结果。
答案 1 :(得分:1)
假设您的ChallengeParticipant
列表合理有界(最多几百个)并且您没有达到每个实体大小限制1M的风险,那么您最好将其保留为嵌入式。< / p>
要执行查询,请先通过电子邮件查找此人,然后按人员过滤:
UserEntity user = // load user (or get the key) by email
ofy().load().type(ChallengeEntity.class).filter("participants.user", user);
请注意,您需要@Index
ChallengeParticipant.user
字段,而不是ChallengeEntity.participants
列表。