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

Objectify: Filter by an attribute of collection entries?

我在 Google 的 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 的需要调整我的实体模型...我如何才能有效地支持这个查询并保持一个好的模型?

非常感谢

假设电子邮件对于用户来说是唯一的,我会将 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;
}

如果您想向挑战中添加新参与者,请在一次事务中更新两个实体(参与者和挑战)。由于不涉及索引,您将始终获得一致的结果。

假设您的 ChallengeParticipant 列表合理限制(最多几百个)并且您没有达到每个实体 1M 大小限制的风险,您最好将其保留为嵌入式.

要执行查询,请先通过电子邮件查找人员,然后按人员筛选:

UserEntity user = // load user (or get the key) by email
ofy().load().type(ChallengeEntity.class).filter("participants.user", user);

请注意,您需要 @Index ChallengeParticipant.user 字段,而不是 ChallengeEntity.participants 列表。