将Objectify索引添加到现有属性和现有实体?

时间:2014-08-18 10:00:16

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

我正在使用Objectify存储实体,现在想在其中一个属性中添加index以运行查询。

实体从通过Google Cloud Endpoints连接的iOS客户端到达。它在由ServiceGenerator生成的Objective-C类中设置属性。

所以我尝试过在Eclipse中为属性添加@Index注释,并使用appcfg再次上传项目。但是,当我在Google Developers Console中检查数据存储区时,仍然会说"没有索引服务"如果我创建新实体并在(现在已索引)属性上运行Objectify查询仍然会返回零项。

那么为了在Eclipse项目中使用Objectify注释定义的现有实体的现有属性添加索引,我必须完成哪些确切的步骤?

This Q& A表明它应该是直截了当的,但由于某种原因它(显然)不是。也许复杂性源于Google Cloud Endpoints和Objective-C客户端的参与。

更新以下是一些相关的代码段,如下所示:

该属性定义如下:

@Entity
@Cache
public class SomeEntity {
    @Id public String someID;
    @Index String someProperty
}

iOS客户端按如下方式设置属性(依赖ServiceGenerator生成的Objective-C类):

someEntity.someProperty = @"someString";

服务器接收并保存实体,如下所示:

@ApiMethod
public AddEntityResponse addEntity(AddEntityRequest request, HttpServletRequest httpServletRequest) throws ServletException {
    SomeEntity someEntity = request.someEntity;
    someEntity.someID = UUID.randomUUID().toString();
    ofy().save().entity(someEntity).now();
    // ...
}

当服务器运行以下查询时,它会返回零项,尽管存在具有给定属性值的实体(例如在数据存储区查看器中可见):

ofy().load().type(SomeEntity.class).filter("someProperty", "someString").list();

4 个答案:

答案 0 :(得分:2)

为了向现有实体添加索引,您必须执行以下简单步骤:

  1. Annotate your properties with @Index
  2. Save the existing entity
  3. 第2点的原因是因为注释您的实体本身是不够的,因为在DataStore中您的数据不受影响。您必须显式重新保存现有实体,以强制Datastore为新注释的属性创建索引。

    同样适用于删除索引时。您必须重新保存才能使更改生效。

    修改

    从您的代码段中我可以看到您的查询不太正确。您正在query返回的对象上调用type(...)方法,该方法实现LoadType接口,但[LoadType][1]扩展的两个接口都没有(即LoadIds和{ {1}}定义该方法!我假设您没有创建自己的包装器,因为您的代码看起来像标准客观化,所以我不确定您的代码是如何编译或在运行时没有爆炸。

    无论如何要修复,因为它看起来像你要做的是按指定的谓词过滤,更改你的查询看起来:

    Query

答案 1 :(得分:1)

是的,我认为应该是直截了当的 - 您只需将@Index注释添加到实体的相应属性中。请记住,这不会影响现有实体,或者通常的类型 - 只是用这个更新的类编写的新实体。

为了验证,我建议您查看新云控制台中的数据存储区查看器。它提供了更多信息,并允许您查看单个实体的索引信息。确保在那里检查新创建的实体。

答案 2 :(得分:1)

当我将新索引属性的看似冗余的赋值添加到服务器上运行的代码时,我可以取得进展并从查询中接收预期的结果。

@ApiMethod
public AddEntityResponse addEntity(AddEntityRequest request, HttpServletRequest httpServletRequest) throws ServletException {
    SomeEntity someEntity = request.someEntity;
    someEntity.someID       = UUID.randomUUID().toString();
    someEntity.someProperty = someEntity.someProperty;
    ofy().save().entity(someEntity).now();
    // ...
}

在存储了一个新实体后,我在Google Developers Console的Cloud Datastore Query(部分)中看到了这个实体,我从应用someProperty过滤器的查询中收到了该实体。 (出于某种原因,Google Developer Console的Cloud Datastore Indexes部分仍然说“没有索引服务”)。

所以我的结论是@Index ed属性的赋值只对指数(以及查询)产生实际影响,如果它们直接在服务器上用Objectify执行(不是间接在iOS客户端上执行,然后传递给具有Google Cloud Endpoints的服务器)。

答案 3 :(得分:0)

我不确定这与索引有何关联,但我知道如果该特定模型中已有数据,修改模型可能会有问题。我在添加属性或在某些

上切换默认值时遇到了问题

我不知道你的情况有多相关,但是你可以用新索引“复制”你的模型,然后将数据迁移到新模型,这应该正确构建该索引吗?

(p.s:是的我知道我要求你“关掉它再打开”;))