java - 查询 Cloud Datastore 中的嵌入式实体

标签 java google-cloud-datastore google-cloud-platform eventual-consistency

我有几个关于在 Datastore 中使用嵌入式实体的问题。

考虑以下简单的测试用例:

Entity entity = new Entity("Person");

entity.setProperty("name", "Alice");
EmbeddedEntity address = new EmbeddedEntity();
address.setProperty("streetAddress", "100 Main Street");
address.setProperty("addressLocality", "Springfield");
address.setProperty("addressRegion", "VA");

entity.setProperty("address", address);

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();
datastore.put(entity);

Query query = new Query("Person");
FilterPredicate regionFilter = 
    new FilterPredicate("address.addressRegion", FilterOperator.EQUAL, "VA");
query.setFilter(regionFilter);

List<Entity> results = datastore.prepare(query)
    .asList(FetchOptions.Builder.withDefaults());

assertEquals(1, results.size());

这个测试失败了;结果集为空。

这是我的问题:

  1. 我是否正确使用了 FilterPredicate?该文档没有解释如何引用 EmbeddedEntity 的属性。我猜约定是使用点分隔的路径。但也许这是不正确的。
  2. 我的测试用例是否需要为嵌入地址实体中的子属性声明索引?如果是,怎么做?

Datastore documentation包含以下语句:

“当嵌入式实体包含在索引中时,您可以查询子属性。”

我正在按照有关 Local Unit Testing 的文章中的说明进行操作对于 Java,但文章中没有任何内容解释如何在 JUnit 测试中定义索引。

最佳答案

由于最终一致性,此测试不稳定。

由于您没有执行祖先查询,因此查询使用最终一致的索引 (SELECT * FROM Person WHERE address.addressRegion = "VA")。不保证插入和查询命中同一个副本,也不保证 address.addressRegion 已更新。

默认情况下,嵌入式实体应该被索引,所以这不是问题。

最终一致性通常在几毫秒内解决,但由于您正在立即编写和查询,因此您更有可能命中它。

您可以采用 2 种策略来减少测试的不稳定性。

1。 sleep

在 put 和查询之间添加 1 或 2 秒的 hibernate 将减少测试的脆弱性,但不会消除它 - 可能是合理的第一步。我没有运行你的代码,乍一看似乎是正确的。

2。强制应用索引写入

Cloud Datastore 将实体同步写入多数副本,但在此步骤之后异步应用索引 - 这会导致某些查询的最终一致性。

您可以通过执行相关实体的读取来强制应用索引。读取实体时,将检查实体组的写入日志以查看是否有任何待应用的未完成写入 - 如果有,则强制在读取之前应用它们。您可以在单元测试中使用此机制来减少最终一致性问题。

杂项

此外,要验证实体是否按预期编写,您可以跳转到云控制台并从上方执行 GQL 语句。

关于java - 查询 Cloud Datastore 中的嵌入式实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41129945/

相关文章:

google-app-engine - Dart-为Google Cloud Datastore的dart数据存储对象插入索引

django - 为什么我在 Google App Engine *开发* 控制台中看不到任何数据?

java - 为什么 Java 泛型不支持原始类型?

java - 当 Class 扩展 JFrame 时,httpunit 不起作用

java - App Engine 中的 JDO : how can an owned relationship be not dependent?

google-cloud-platform - GCP secret 版本在变得不可见之前会保持销毁状态多长时间?

node.js - 将 Node 应用程序部署到 GAE : Cannot find module 'v8-compile-cache'

python - Google Pub/Sub Subscriber 一段时间后收不到消息

java - SetBackgroundColor 影响多个列表项

java - 构建签名APK时android studio中的gradle问题