gpt4 book ai didi

google-app-engine - 未知数量的数据存储过滤器的 Golang 实现(需要附加过滤器的功能)

转载 作者:IT王子 更新时间:2023-10-29 02:03:34 24 4
gpt4 key购买 nike

我正在开发一个网络应用程序,用户可以在其中选择不同的选项,例如应用程序价格、星级数量、更新时间等。

问题是,使用 Datastore 之后只能制作 1 个不等式过滤器,所以我不能说:

query = datastore.NewQuery("iOSApp").Filter("StarRatings >=", stars).Filter("MinimumAge >=", age).Filter("Price >=", price)

相反,我添加了几个 bool/int 实体,这样如果我想说 StarRatings 大于 3(最大值为 5),那么我可以说:

query = datastore.NewQuery("iOSApp").Filter("Stars2Up =", false).Filter("Stars3Up =", true)

这个解决方案似乎工作得很好(我相信这是一个好的/快速的解决方案,尽管我可能是错的)

我现在遇到的问题是执行此查询的函数必须执行如此多的检查。下面的代码仅检查 StarRating 过滤器,但我还想过滤年龄、价格、下载、更新时间等.

var query *datastore.Query
switch stars {
case 1:
query = datastore.NewQuery("AppStoreApp").Filter("Stars1Up =", true)
case 2:
query = datastore.NewQuery("AppStoreApp").Filter("Stars1Up =", false).Filter("Stars2Up =", true)
case 3:
query = datastore.NewQuery("AppStoreApp").Filter("Stars2Up =", false).Filter("Stars3Up =", true)
case 4:
query = datastore.NewQuery("AppStoreApp").Filter("Stars3Up =", false).Filter("Stars4Up =", true)
case 5:
query = datastore.NewQuery("AppStoreApp").Filter("Stars3Up =", false).Filter("Stars4Up =", true)
default:
log.Println("error...")
}
var app []iOSApp
if _, err := db.client.GetAll(ctx, query, &app); err != nil {
log.Fatalf("err: ", err)
}
return &app, nil

如果我尝试使用 if/else 或 switch case 来做到这一点,那么我很快就会得到一千种不同的 if/else/switch 场景。所以我想我可以添加一个函数来接受查询和属性作为输入,然后作为输出,它将返回包含它的新过滤器的查询。

例如

// query before
query = datastore.NewQuery("AppStoreApp").Filter("Stars1Up =", false).Filter("Stars2Up =", true)

query, err = appendFilter(query, updatetime) // in this case updatetime = within 6 months as an example

// query after
query = datastore.NewQuery("AppStoreApp").Filter("Stars1Up =", false).Filter("Stars2Up =", true).Filter("UpdatedWithin6Months =", true).Filter("UpdatedWithin1Year =", false)

对于如何实现此 appendFilter 函数,我将不胜感激

最佳答案

Query.Filter()方法返回一个派生查询,该查询将包含调用它的查询的所有过滤器,以及您在其参数中指定的过滤器。因此,如果您计划分多个步骤构建最终查询,则需要存储其返回值。

所以你的 appendFilter() 是不必要的,你可以这样做:

q := datastore.NewQuery("AppStoreApp")

// Append a filter:
q = q.Filter("filter1", value1)

// Append another filter:
q = q.Filter("filter2", value2)

要优化您的“星星”过滤器,可以这样做:

func applyStarFilter(q *datastore.Query, minStars int) *Query {
if minStars > 1 {
q = q.Filter(fmt.Sprintf("Stars%dUp =", minStars-1), false)
}
return q.Filter(fmt.Sprintf("Stars%dUp =", minStars), true)
}

利用具有枚举值的字段

您的 UpdatedWithinXXYY 字段与星号非常相似:具有固定的枚举值,要根据它进行过滤,您需要设置 2 个过滤字段(一个 true 和一个错误)。

如果您提前枚举这些,则可以自动设置这 2 个字段。例如:

func applyUpdatedWithin(q *datastore.Query, updateIdx int) *Query {
q = q.Filter(updatedValues[updateIdx], true)
if updateIdx+1 < len(updatedValues) {
q = q.Filter(updatedValues[updateIdx+1], false)
}
return q
}

var updatedValues = []string{
"UpdatedWithin1Day =",
"UpdatedWithin1Week =",
"UpdatedWithin1Month =",
"UpdatedWithin1Year =",
}

应用最小 3 星和 UpdatedWithin6Months 的示例:

q := datastore.NewQuery("AppStoreApp")
q = applyStarFilter(q, 3)
q = applyUpdatedWithin(q, 2)

与您的情况相关,为了规划您的数据存储区索引,我强烈建议阅读这篇文章:

Index Selection and Advanced Search

关于google-app-engine - 未知数量的数据存储过滤器的 Golang 实现(需要附加过滤器的功能),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42114198/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com