在 objectify 中加载项目列表

Load list of items in objectify

我有问题、喜欢和标签实体。 Like 和 Question 实体之间也存在一对多关系。我正在使用 google 云端点,我的问题从这里开始。在我的列表方法中,我 return 20 个问题为 json。但是对于查询中的每个问题对象,我必须检查用户是否已经喜欢这个问题并且还获取属于该问题的相关主题标签。我怎样才能通过仅键批量查询来执行相同的操作。否则,我

ofy().load().type(Like.class)
                .filter("questionRef =", questionKey)
                .filter("accountRef =", accountKey).first().now();

每个对象。

喜欢实体

@Entity
@Cache
public class Like {

  @Id
  @Getter
  protected Long id;

  @Index
  @Load
  @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
  private Ref<Account> accountRef;

  @Index
  @Load
  @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
  private Ref<Question> questionRef;

  @Index
  @Getter
  protected Date createdAt;

  Like() {
  }

  Like(Key<Account> accountKey) {
    this.accountRef = Ref.create(accountKey);
    this.createdAt = new Date();
  }
}

标签实体

@Entity
@Cache
public class Hashtag implements Model<Hashtag> {

  @Id
  @Getter
  @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
  private Long id;

  @Index
  @Load
  @ApiResourceProperty(ignored = AnnotationBoolean.TRUE)
  private Ref<Question> questionRef;

  @Index
  @Getter
  @Setter
  private String text;

  private Hashtag() {
  }

  private Hashtag(Builder builder) {
    this.questionRef = builder.questionRef;
    this.text = builder.text;
  }
}

我不确定您是否可以更改实体的结构。如果答案是否定的,那么除了您所采用的方法之外别无选择。

如果是,我建议构建您的 Question 以包含 LikeHashtag 信息。

@Entity
public class Question {
    @Id
    private long id;
    private Set<Key<Account>> likedBy;
    private List<String> hashtags;
}

对于一个问题,您可以在一个查询中检索所有信息。然后收集所有 Account 键并进行另一个数据存储查询,以使用如下键检索所有喜欢该问题的人:

Map<Key<Account>, Account> likedByAccounts = ofy().load().keys(accountKeys);

这个问题有几个部分。

首先,主题标签:只需将主题标签作为索引列表存储在问题中 属性。简单。

其次,喜欢:有几种方法可以有效地做到这一点。

一种是创建一个自然键为 "account:question" 的 Like 实体(使用字符串化的网络安全键)。通过这种方式,您可以通过键对所有 {user,question} 元组进行批量获取。有些人会缺席,有些人会在场。如果您只关心 20 个问题,效率相当高,尤其是如果您 @Cache 点赞。

另一种方法是创建一个单独的关系索引实体,用于跟踪用户的所有点赞,并且每次都加载它们。您可以在任何列表 属性 中放置 5k 项,这意味着当用户喜欢超过 5k 项时,您将需要兼顾多个实体。但是使用单个祖先查询很容易将它们全部加载起来。 RIE 需要由用户@Parent编辑。

单独说明 - 不要调用字段 thingRef。只是一个thing。数据库中的数据只是一个键。您可以互换 Ref<?>Key<?> 和原生低级 Key。类型信息不属于数据库名称。