如何重命名数据存储实体字段但能够通过新旧属性名称检索记录?

Wil*_*iam 1 google-app-engine objectify google-cloud-datastore

我有一个实体

class Foo {
  public String bar;
}
Run Code Online (Sandbox Code Playgroud)

我想将“bar”重命名为“somethingElse”。并计划使用 Objectify 的 @AlsoLoad 注释来实现这一目标(我已经在使用 Objectify 进行持久化)。所以像这样:

class Foo {
  @AlsoLoad("bar")
  public String somethingElse;
}
Run Code Online (Sandbox Code Playgroud)

但任何形式的查询:

final Query<Foo> query = OfyService.ofy().load().type(Foo.class)
    .filter("somethingElse", "someValue");
Run Code Online (Sandbox Code Playgroud)

仅检索自重命名以来已保存的实体。任何较旧的实体都将被忽略。

重命名实体字段以便我可以通过单个查询返回所有记录的最佳实践是什么?

Dan*_*scu 5

注意:我不是客观化用户,答案是通用的,因此您必须对其进行调整以适应客观化细节。

一般来说,您希望避免长时间使用bar和,主要是因为查找匹配实体会转换为一种查询类型 - OR,而数据存储根本上不支持这种查询。来自查询限制somethingElseOR.filter("bar", "someValue") .filter("somethingElse", "someValue")

、和运算符NOT本身不受支持,但某些客户端库可能会在 Cloud Datastore 之上添加支持。OR!=

这意味着,您最多只能跳过重重困难才能完成类似的工作,例如,请参阅Google Datastore 组合(联合)多组实体结果以实现 OR 条件

我的建议是执行一次性迁移并完成它。它将包含以下步骤:

  • 最有可能的是,您必须在迁移期间配置/激活这两个属性,因此不要只是重命名bar,而是添加somethingElse并且不要立即删除bar
  • 在您更新属性的所有地方bar也会somethingElse相应更新
  • 添加逻辑来查询所有具有bar但不具有的实体somethingElse,并重写它们,以便它们也具有somethingElse. 此步骤完成后,所有实体都应具有somethingElse镜像bar
  • 在您读取值的所有非查询位置bar切换为somethingElse读取
  • 检查包含的所有索引somethingElse是否正在服务,然后将查询从 切换barsomethingElse。至此,实际迁移已完成,您可以执行以下清理步骤
  • 放弃写入bar属性
  • 对具有属性的所有实体执行查询bar并在不使用bar. 请注意,这可能比实际留下这些实体更昂贵
  • 从您的模型和索引中删除bar(如果适用于您的客户端库),但前提是您在上一步中从所有实体中删除了该属性

采用这种方法的迁移可以缓慢执行,因为它不需要完全关闭服务,可以实时完成。