Google app engine 带筛选器的AppEngine数据存储查询从不返回结果(Go)

Google app engine 带筛选器的AppEngine数据存储查询从不返回结果(Go),google-app-engine,go,google-cloud-datastore,Google App Engine,Go,Google Cloud Datastore,如果我不使用过滤器,我会得到结果。如果我使用过滤器(这个记录肯定存在),我不会得到任何结果。这可能是因为缺少为该属性定义的索引,但据我所知,应该在开发服务器中自动创建简单的索引(以及创建并填充的index.yaml文件)。这并没有发生 query = datastore.NewQuery("UserAccount").Filter("email =", "test@example.com") ua := UserAccount{} t := query.Run(ctx) for ; ; {

如果我不使用过滤器,我会得到结果。如果我使用过滤器(这个记录肯定存在),我不会得到任何结果。这可能是因为缺少为该属性定义的索引,但据我所知,应该在开发服务器中自动创建简单的索引(以及创建并填充的index.yaml文件)。这并没有发生

query = datastore.NewQuery("UserAccount").Filter("email =", "test@example.com")

ua := UserAccount{}
t := query.Run(ctx)
for ; ; {
    if _, err = t.Next(&ua); err == nil {
        log.Debugf(ctx, "Current: %s", ua)
    } else if err == datastore.Done {
        break
    } else {
        panic(err)
    }
}
当开发服务器终止时,它声明它正在“保存搜索索引”:

但是,由于没有出现“index.yaml”文件,我假设不需要创建索引,这意味着我的查询一定没有达到预期效果

我错过了什么

编辑:

请注意,该记录是以前创建的,此后应用程序多次停止和启动。我真诚地怀疑这是最终的一致性问题

编辑2:

为了进行测试,我使用以下代码创建了以下模型。它们都表现出与我的原始模型和代码相同的行为

定义:

type TestEntity struct {
    Email string
}
代码:

结果:

2016/08/09 02:11:36 DEBUG: Putting.
2016/08/09 02:11:36 DEBUG: Waiting.
2016/08/09 02:11:37 DEBUG: GetAll: [{anothertest@a.b}]
2016/08/09 02:11:37 DEBUG: Running query.
2016/08/09 02:11:37 DEBUG: Done.
观众截图:


若要通过属性在查询/筛选结果中查找实体,该属性在创建实体时必须启用索引(在模型定义中),并且必须完成数据存储的后台索引任务

如果在创建实体后为该属性启用索引,则需要重新写入该属性,以便为其触发索引任务,请参阅:

“保存搜索索引”消息是在操作发生之前打印的通用消息,并不意味着操作的结果将是非空的

您不必担心
index.yaml
文件是空的。并非所有索引都需要出现在
index.yaml
文件中,只有更复杂/复合的索引需要出现。您的过滤器可以使用内置索引进行匹配(在满足上述索引要求之后)。发件人:

有两种类型的索引:

  • 内置索引

    默认情况下,云数据存储自动为每种实体类型的每个属性预定义索引。这些单一属性索引是 适用于简单类型的查询

  • 综合指数

    复合索引为每个索引实体索引多个属性值。复合索引支持复杂查询,并在中定义 索引配置文件(index.yaml)


数据存储中的属性名称是带大写字母E的
“Email”
,而不是
“Email”

它区分大小写,必须使用大写字母E查询:

query = datastore.NewQuery("UserAccount").Filter("Email =", "test@example.com")
如果您希望使用小型
e
保存/检索它,您可以使用来进行映射,例如:

type UserAccount struct {
    Email string `datastore:"email"`
    // other fields...
}

这是因为最终的一致性。请参阅可能的副本:1;2.3.请确认这是否解决了您的问题。@icza它没有。记录以前存在(读取:在当前开发服务器启动之前)。它不仅仅是创建的。您确定您有一个确切的
用户帐户
实体,该实体具有
“email”
属性并具有
test@example.com“
?请在这个可能的副本上检查我的答案,并确认是否所有测试都通过:@icza有几点不错,但没有一点适用。我使用具有不同值的不同记录进行了验证。这太荒谬了。现在还不清楚如何标记属性以进行索引,或者它是否被支持。文档仅在防止索引的上下文中提到标记:()“Age int
数据存储:”,noindex“
”实际上,go在这方面似乎与python不同。答案仍然适用-在创建实体时,您可能已经禁用了索引:)@DustinOprea:您可以在云控制台数据存储查看器中查看属性是否已被索引。找到一个实体并单击“编辑”图标-它将显示所有属性。@AndreiVolgin我从未对该列进行过搜索,但我的理解是,简单的索引是隐式创建的。然而,情况似乎并非如此。我尝试创建一个带有一些语法错误的index.yaml来测试它是否会被加载(如果启动时出现错误,那么显然有人试图加载它),我可以有效地在那里添加一个显式的。然而,开发环境在启动时似乎完全忽略了它。有什么想法吗?@DustinOprea我怀疑devserver在遇到需要复合索引的查询时只读取
index.yaml
文件,以检查是否需要将索引添加到文件中。尝试在您的代码中添加一个复合查询来测试这一理论-开发服务器应该要么因为不正确的现有
index.yaml
文件而呕吐,要么如果理论正确,很高兴从头开始重新生成它。感谢您注意到我自己太笨而没有注意到的东西。那是一个有趣的消息。至少我们确定了看到“未索引”东西的可能性。另外,我得到了结果,但我仍然没有在管理员或“index.yaml”文件中看到任何索引。正如DanCornilescu之前提到的,不能表示简单的索引(这似乎会使计算写操作的成本估算更加困难)。最后,我注意到,当我在Go(“goapp-serve”)下运行AppEngine版本时,我得到一个脚注,上面说它包装了Python开发服务器。@dustinorea只需要将复合索引添加到
index.yaml
。单一属性指数不适用。单个属性索引基于每个实体存在:一个实体可能有一个已索引的
电子邮件
属性,另一个实体可能有一个未索引的
电子邮件
属性,第三个实体甚至可能没有这样的属性。即使是第四个也可能有一个,但有不同的类型。。。数据存储不是关系数据库,它是无模式的。@dustinprea是的,GoSDK使用python开发服务器,这不是秘密。我希望
query = datastore.NewQuery("UserAccount").Filter("Email =", "test@example.com")
type UserAccount struct {
    Email string `datastore:"email"`
    // other fields...
}