Objectify:按集合条目的属性过滤?

时间:2015-06-07 11:13:29

标签: google-app-engine collections objectify

我在谷歌的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的需求......我怎样才能有效地支持 这个查询并保持一个好的模型?

非常感谢

2 个答案:

答案 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列表。