Google app engine 仅数据存储密钥定价&;围棋的实施
我知道KeysOnly查询更便宜,但我想知道我是否正确地实现了它 例如,如果我为KeysOnly(如下所示)创建了一个Google app engine 仅数据存储密钥定价&;围棋的实施,google-app-engine,go,google-cloud-datastore,Google App Engine,Go,Google Cloud Datastore,我知道KeysOnly查询更便宜,但我想知道我是否正确地实现了它 例如,如果我为KeysOnly(如下所示)创建了一个GetAllfunc,那么我是否仍应该初始化users结构([]User) 此外,如果我只想获取一个直接调用的键(我已经知道namekey,在本例中是,namekey==username),以检查该键是否存在,那么正确的方法是什么 现在我喜欢这样: func GetUserByNameKey(ctx context.Context, key *datastore.Key) (Us
GetAll
func,那么我是否仍应该初始化users结构([]User
)
此外,如果我只想获取一个直接调用的键(我已经知道namekey,在本例中是,namekey==username
),以检查该键是否存在,那么正确的方法是什么
现在我喜欢这样:
func GetUserByNameKey(ctx context.Context, key *datastore.Key) (User, error) {
var user User
err := DatastoreClient().Get(ctx, key, &user)
if err != nil {
return user, err
}
return user, nil
}
func GetAllUserKeysByFilter(ctx context.Context, filters ...UserFilter)
([]*datastore.Key, error) {
query := datastore.NewQuery("User").KeysOnly()
for _, filter := range filters {
if filter.Age != 0 {
query = query.Filter("Age =", filter.Age)
}
if filter.Limit != 0 {
query = query.Limit(filter.Limit)
}
}
keys, err := DatastoreClient().GetAll(ctx, query, nil)
if err != nil {
return nil, err
}
return keys, nil
}
但是,由于我只关心用户密钥是否存在,它能否以某种方式转换成更便宜的密钥
使用GetAllUserKeysByFilter
和Limit==1
?查询/获取操作成本可能会更便宜
Get操作(按键获取)的成本是1个读取操作(并且没有小的操作)。键是否有一个实际的实体在成本方面并不重要:两者都将花费您1个阅读操作。“困难”部分是找到键的实体,或者发现没有这样的实体,返回的结果是“简单”部分
对于每个结果(对于每个结果键),仅键查询的成本为1个读取操作+1个小操作
为了完整性,对于每个返回的实体,“普通”查询(不仅仅指键)的成本是1个read op+1个read op
示例:返回10个实体的普通查询是11个读取操作。返回10个键的仅键查询是1个读取操作+10个小操作。Get调用是1个read op(无论是否找到并返回实体)
因此,用limit=1
调用GetAllUserKeysByFilter()
理论上会花费更多:它需要1次读取操作和1次小操作。但由于小规模运营是免费的(不需要真正的资金),它们基本上是平等的。但是要知道,除非您的实体很大,否则Get()
操作(按键)可能会更快。如果实体较大,请使用带有limit=1
的仅关键帧查询。如果您的实体很小,Get()
很可能会更快(如果它对您有影响,请进行测量)
有关查询成本的一些信息可在此页面上找到:
仅键查询示例
您对仅密钥查询的实现是不必要的复杂。当您执行仅限键查询时,的dst
destination参数被省略(未使用),只有返回值是有用的,即:结果键的切片:
如果q是“仅键”查询,则GetAll忽略dst并仅返回键
因此,基本上您的解决方案也可以工作,但不会使用users
切片。您的GetAllUserKeysByFilter()
函数应该如下所示:
func GetUserByNameKey(ctx context.Context, key *datastore.Key) (User, error) {
var user User
err := DatastoreClient().Get(ctx, key, &user)
if err != nil {
return user, err
}
return user, nil
}
func GetAllUserKeysByFilter(ctx context.Context, filters ...UserFilter)
([]*datastore.Key, error) {
query := datastore.NewQuery("User").KeysOnly()
for _, filter := range filters {
if filter.Age != 0 {
query = query.Filter("Age =", filter.Age)
}
if filter.Limit != 0 {
query = query.Limit(filter.Limit)
}
}
keys, err := DatastoreClient().GetAll(ctx, query, nil)
if err != nil {
return nil, err
}
return keys, nil
}
另外,如果您想将
GetAllUserKeysByFilter()
重复用于仅键查询和普通查询,您可以继续这样做,但是您还应该返回users
切片。非常感谢,非常感谢:)!。。我也能感觉到只有按键的功能出了问题。。我曾想通过让同一个函数同时适用于keysonly和常规getall查询而变得“聪明”(最初有一个keysonly过滤器,它会添加query=query.keysonly()
,但感觉不对..PS:毫无疑问,你是我最喜欢的SO用户:)@fisker基本上,您可以继续将原始的GetAllUserKeysByFilter()
用于仅键查询和普通查询(仅用户
切片将不用于仅键查询),但您还应该返回用户
切片。稍微更新了答案。非常感谢,非常感谢:)!