代码之家  ›  专栏  ›  技术社区  ›  fisker

Go中的数据存储仅密钥定价和实施

  •  1
  • fisker  · 技术社区  · 8 年前

    我知道纯键查询更便宜,但我想知道我是否正确实现了它。

    GetAll []User )?

    func GetAllUserKeysByFilter(ctx context.Context, filters ...UserFilter) ([]*datastore.Key, error) {
        var users []User
        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, &users)
        if err != nil {
            return nil, err
        }
        return keys, nil
    }
    

    此外,如果我只想获取直接调用的键(我已经知道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
    }
    

    但是,由于我只关心用户密钥是否存在,它是否可以以某种方式转换为更便宜?

    也许使用 GetAllUserKeysByFilter Limit == 1 ?

    1 回复  |  直到 8 年前
        1
  •  2
  •   icza    8 年前

    查询/获取运营成本

    对于每个结果(对于每个结果键),仅键查询的成本为1个读取操作+1个小操作。

    为了完整性,“正常”查询(不仅仅指键)的成本是每个返回实体的1个读取操作+1个读取操作。

    示例:返回10个实体的普通查询是11个读取操作。返回10个键的仅键查询是1个读取操作+10个小操作。Get调用是1个读操作(无论是否找到并返回实体)。

    GetAllUserKeysByFilter() limit = 1 成本更高:它需要1个读取操作和1个小操作。但由于小型运营是免费的(没有实际成本),它们基本上是平等的。但是要知道 Get() 除非您的实体很大,否则操作(按键)可能会更快。如果实体较大,请使用仅关键帧查询 极限=1 . 如果您的实体较小, 很可能会更快(如果这对你来说很重要,请测量)。

    Datastore Queries

    仅键查询示例

    dst 的目标参数 Query.GetAll()

    如果q是一个仅键查询,则GetAll忽略dst并仅返回键。

    所以基本上你的解决方案也是可行的,但是 users GetAllUserKeysByFilter() 函数应如下所示:

    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
    }
    

    P、 如果你想重复使用 GetAllUserKeysByFilter() 用户