使用golang在google app引擎数据存储上执行"IN Array"查询

Ste*_* Lu 5 google-app-engine go google-cloud-datastore

有没有办法ids []int64在数据存储区上进行查询?我试过以下但没有用.

  1. 错误

    q := datastore.NewQuery("Category").Filter("Id IN", ids)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 只需获取数据存储区中的所有类别即可

    for _, id := range ids {
        q.Filter("Id =", id)
    }
    
    Run Code Online (Sandbox Code Playgroud)

在icza的回答之后

var keys []*datastore.Key

for _, id := range ids {
    keys = append(keys, datastore.NewKey(c, "Category", "", id, nil))
}

categories := make([]Category, len(keys))
err := datastore.GetMulti(c, keys, categories)
if err != nil {
    return nil, err
}
Run Code Online (Sandbox Code Playgroud)

icz*_*cza 5

通常"IN",数据存储区不支持过滤器.Query.Filter()列出允许的运算符的文档:

">", "<", ">=", "<=", or "="
Run Code Online (Sandbox Code Playgroud)

您可以做的是为要过滤的数组中的每个元素执行单独的查询.此外,如果该元素是在连续的范围,您可以替换INid>=minid<=max.例如:

ids := []int64{1,2,3,4}
q := datastore.NewQuery("Category").Filter("Id>=", 1).Filter("Id<=", 4)
Run Code Online (Sandbox Code Playgroud)

另请注意,虽然IN通常不支持,但如果属性是实体键本身,则可以使用以下datastore.GetMulti()函数获取由其键的数组指定的实体列表:

func GetMulti(c appengine.Context, key []*Key, dst interface{}) error
Run Code Online (Sandbox Code Playgroud)

注意:

您的第二次尝试返回所有实体,因为您调用Filter()了查询,但是您没有存储返回值,因此您最终执行的查询根本没有过滤器.Query.Filter()返回包含您刚刚指定的过滤器的衍生查询,您必须使用返回的Query正在进行的查询.所以它应该是:

q = q.Filter("Id=", id)
Run Code Online (Sandbox Code Playgroud)

但即使这样也不会起作用:如果指定了多个过滤器,它们将处于逻辑AND连接中,因此我很可能会给你0个结果,因为我怀疑没有类别存在于哪里Id是一个列表,哪个将包含所有id想要过滤.