在物化中加载项目列表

时间:2016-07-04 15:11:06

标签: google-app-engine google-cloud-endpoints objectify

我有问题,喜欢和Hashtag实体。 Like和Question实体之间也存在一对多的关系。我正在使用谷歌云终端,我的问题从这里开始。在我的list方法中,我将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();
  }
}

Hashtag实体

@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;
  }
}

2 个答案:

答案 0 :(得分:3)

这个问题有几个部分。

首先,hashtags:只需将问题中的主题标签存储为索引列表属性。容易。

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

一个是使用&#34; account:question&#34;的自然键创建一个Like实体。 (使用字符串化的网络安全密钥)。这样,您可以为所有{user,question}元组执行批量get by key。有些人将缺席,有些人将出席。如果你只关心20个问题,那就合理有效,特别是如果你@Cache喜欢这样的话。

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

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

答案 1 :(得分:0)

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

如果是,我建议您构建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);