【问题标题】:GAE datastore querying integer fieldsGAE 数据存储查询整数字段
【发布时间】:2012-12-12 19:11:50
【问题描述】:

我在查询 GAE 数据存储时发现了奇怪的行为。在某些情况下,过滤器不适用于整数字段。下面的java代码重现了这个问题:

log.info("start experiment");

DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

int val = 777;

// create and store the first entity.
Entity testEntity1 = new Entity(KeyFactory.createKey("Test", "entity1"));
Object value = new Integer(val);
testEntity1.setProperty("field", value);
datastore.put(testEntity1);

// create the second entity by using BeanUtils.
Test test2 = new Test(); // just a regular bean with an int field
test2.setField(val);

Entity testEntity2 = new Entity(KeyFactory.createKey("Test", "entity2"));

Map<String, Object> description = BeanUtilsBean.getInstance().describe(test2);
for(Entry<String,Object> entry:description.entrySet()){
    testEntity2.setProperty(entry.getKey(), entry.getValue());
}

datastore.put(testEntity2);


// now try to retrieve the entities from the database...

Filter equalFilter = new FilterPredicate("field", FilterOperator.EQUAL, val);

Query q = new Query("Test").setFilter(equalFilter);

Iterator<Entity> iter = datastore.prepare(q).asIterator();

while (iter.hasNext()) {
    log.info("found entity: " + iter.next().getKey());
}

log.info("experiment finished");

日志如下所示:

INFO: start experiment
INFO: found entity: Test("entity1")
INFO: experiment finished

由于某种原因,即使两个实体都实际存储在数据存储中并且两个“字段”值都是 777(我在数据存储查看器中看到),它也只能找到第一个实体!为什么实体的创建方式很重要?我想用 BeanUtils,因为它很方便。

在本地开发服务器和部署到 GAE 时会出现同样的问题。

【问题讨论】:

  • 我们能否获得更多信息。特别是代码/图表。
  • 没人知道吗?所以我可以试试JDO。当即使非常简单的编码失败时,它也不会让我对使用如此复杂的框架充满信心。

标签: java google-app-engine google-cloud-datastore apache-commons-beanutils


【解决方案1】:

好的,我知道发生了什么。 “问题”是由于某种原因 BeanUtils 将整数转换为字符串。字符串在数据存储查看器中看起来完全一样,但它当然不一样。这几乎愚弄了我。我应该研究过 apache BeanUtils 手册之类的。

【讨论】:

    【解决方案2】:

    您是否在写入后 1 秒后才查询数据?有时您不必(也许是祖先查询),但有时您必须这样做。 GAE/J 文档将提供完整的详细信息。

    【讨论】:

    • 是的,我做到了。我可以多次重复这个实验。它总是一样的。实际上我有数百个条目的表,我无法查询任何整数字段,可能是因为我使用 Apache BeanUtils 创建了它们。
    【解决方案3】:

    实体是用 BeanUtils 创建的这一事实完全无关紧要。如果实体在数据存储中(您可以在查看器中看到它们)并且字段值已编入索引(它不会在数据存储查看器中的值旁边显示“未索引”),那么您可以使用过滤器查询它们。这行得通……这是数据存储的基本功能。

    鉴于实体已创建和索引,我建议 Ian Marshalls 的建议可能是正确的。要对此进行测试,请转到 App Engine 的首选项并取消勾选“启用本地 HRD 支持”。这将确保您在编写 Entity 时可以立即对其进行查询。

    如果您存储 Integer 或 int 或任何其他数值并不重要 - 它们都在内部存储为 long 值,当您读回您的值时,您将获得 Long(尽管存储了 Integer)

    【讨论】:

    • 我也希望这完全无关紧要。我取消勾选“启用本地 HRD 支持”,它仍然是一样的。
    • 我在数据存储查看器中看到两个实体,并且两个“字段”值都是 777(无法发布屏幕截图,因为我的声誉不够高)。没有“未索引”。这和查询索引有关吗?
    猜你喜欢
    • 2013-06-21
    • 1970-01-01
    • 2018-08-12
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多