问题:用户(B)需要基于某些标准从一组用户(A)获得帮助。用户(A)在其个人资料中设置此标准。
class UsersAProfiles(db.Model):
industries = db.StringListProperty() #technology, etc. (total 20)
agegroups = db.StringListProperty() #teenagers, etc. (total 10)
tags = db.StringListProperty() #cooking, etc.
(while each User A can enter at most 10 tags, but there is no limit on
what tags are used, e.g., sql, gym, etc. (limited by dictionary!)
... #there are many other properties
用户(B)设置单独存储的标准
class UserBRequestForHelp(db.Model):
myindustries = db.StringListProperty() #technology, etc. (<20)
myagegroups = db.StringListProperty() #teenagers, etc. (<10)
mytags = db.StringListProperty() #cooking, etc.
... #there are many other properties
现在我需要所有可能帮助B的用户A的列表。为此,我尝试运行以下查询:
query = db.GqlQuery("SELECT * FROM UsersAProfiles WHERE
industries IN :1 AND
agegroups IN :2 AND
tags IN :3",
userB_obj.myindustries , userB_obj.myagegroups, userB_obj.mytags)
但是我收到以下错误:
Cannot satisfy query -- too many IN/!= values.
我真的被困在这里,不知道如何解决这个问题。如何运行此类查询。此外,我是否需要以不同方式设计模型类,以便我可以运行此类查询?如果是,请有人帮忙。
提前感谢!
答案 0 :(得分:0)
当您使用IN创建查询时,GAE必须将该查询分解为多个“index = value”子查询,执行每个子查询并收集组合它们的结果,就像它们是一次搜索一样。查询可以扩展到的子查询数量有限制,that limit is 30。如果您正在使用31个子查询创建查询,那么这将解释您遇到此问题的原因。换句话说,你的情况是len(userB_obj.myindustries)+ len(userB_obj.myagegroups)+ len(userB_obj.mytags)&gt; 30。
答案 1 :(得分:0)
对于上述问题,以下方法可能有用。
在单独的模型中列出TAGS,其中列出了所有匹配的UserA配置文件。
class TAGS(db.Model):
UserAIds = db.StringListProperty()
在上面,每个标签都是关键。 (标签=技术,青少年,烹饪等)
当用户B设置条件,然后找到匹配的用户A时,我们可以运行的查询如下:
i = 0
for industry in userB_obj.myindustries:
t1_obj[i] = TAGS.get_by_key_name(industry)
i = i + 1
(在上面的t1_obj [i]中,您有具有匹配行业的用户A个人资料列表)
j = 0
for agegroup in userB_obj.myagegroups:
t2_obj[j] = TAGS.get_by_key_name(agegroup)
j = j + 1
(在上面的t2_obj [j]中,您有具有匹配年龄组的用户A个人资料列表)
k = 0
for tag in userB_obj.mytags:
t3_obj[k] = TAGS.get_by_key_name(tag)
k = k + 1
(在上面的t3_obj [k]中,您有具有匹配标签的用户A个人资料列表)
接下来,您需要做的就是找到所有三个中存在的UserA配置文件,即t1_obj,t2_obj,t3_obj,这就是全部! 现在找到上面所有3中出现的UserA配置文件,不确定是否有可以执行此操作的python函数。但是,使用模型实例,您可以按如下方式解决它
class MatchingUserAs(db.Model):
count = db.IntegerProperty(default=0)
source = db.StringProperty(default=None)
(在上面的模型类中,UserA id是键。此UserAids存储在t1_key [i] .UserAIds,t2_key [j] .UserAids,t3_key [k] .UserAIds)
现在,遍历t1_obj [i],t2_obj [j],t3_obj [k]并在MatchingUserAs中插入UserA id,并在每次插入行/更新行时将计数递增1。
<"loop through t1_obj[i]">:
Matchkey = MatchingUserAs.get_or_insert(t1_obj[i].UserAId)
Matchkey.count = 1
Matchkey.source = 'industry'
Matchkey.put()
<"loop through t2_obj[j]">:
Matchkey = MatchingUserAs.get_or_insert(t2_obj[j].UserAId)
#the following if check has been added to avoid incrementing the counter
#when same UserAid is present in, say, t2_obj[0], and t2_obj[1], etc.
if(Matchkey.source != 'agegroup')
Matchkey.count = Matchkey.count + 1
Matchkey.source = 'agegroup'
Matchkey.put()
<"loop through t3_obj[j]">:
Matchkey = MatchingUserAs.get_or_insert(t3_obj[j].UserAId)
if(Matchkey.source != 'tags')
Matchkey.count = Matchkey.count + 1
Matchkey.source = 'tags'
Matchkey.put()
现在,您需要做的就是从MatchingUserAs获取那些UserAs,其数量为3(因为我们要匹配3个标记列表:行业,年龄组和标签)。
上面的代码示例中可能存在一些语法错误,特别是对于密钥和对象的使用;在某些情况下,使用了伪代码。我只是想概述解决方案。希望这可以帮助。随意分享任何意见。