繁体   English   中英

查询Cloud Datastore中的嵌入式实体

[英]Querying embedded entities in Cloud 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. 我的测试用例是否需要为嵌入式地址实体中的子属性声明索引? 如果是这样,怎么样?

数据存储文档包含以下语句:

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

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

由于最终的一致性,该测试是片状的。

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

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

最终的一致性通常以毫秒为单位进行解决,但由于您正在立即编写和查询,因此您更有可能获得它。

您可以采用两种策略来降低测试的薄脆度。

睡觉

在put和查询之间添加1或2秒的睡眠将减少测试的瑕疵,但不能消除它 - 可能是合理的第一步。 我一眼就看出它没有运行你的代码。

2.强制应用索引写入

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

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

杂项。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM