我正在使用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();
答案 0 :(得分:2)
为了向现有实体添加索引,您必须执行以下简单步骤:
Annotate your properties with @Index
Save the existing entity
第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:是的我知道我要求你“关掉它再打开”;))