谷歌应用引擎 - 如何对ndb查询返回的结果进行python ndb查询?



我正在为一个项目使用 GAE python (webapp2( 框架,并且有一个与 ndb 查询相关的问题。让我举一个例子来清楚地解释这一点:

这是我拥有的ndb模型:

class Example(ndb.Model):
userid = ndb.StringProperty()
field1 = ndb.StringProperty()
field2 = ndb.StringProperty()

以下是我使用上述模型创建的实体:

[Example(key=Key('Example', '1~A~B'), field1=u'B', field2=u'A', userid=u'1'),
Example(key=Key('Example', '1~C~D'), field1=u'D', field2=u'C', userid=u'1'),
Example(key=Key('Example', '2~A~B'), field1=u'B', field2=u'A', userid=u'2'),
Example(key=Key('Example', '2~C~D'), field1=u'D', field2=u'C', userid=u'2'),
Example(key=Key('Example', '3~A~B'), field1=u'B', field2=u'A', userid=u'3'),
Example(key=Key('Example', '3~X~Y'), field1=u'Y', field2=u'X', userid=u'3'),
Example(key=Key('Example', '4~C~D'), field1=u'D', field2=u'C', userid=u'4'),
Example(key=Key('Example', '4~E~F'), field1=u'F', field2=u'E', userid=u'4'),
Example(key=Key('Example', '5~A~B'), field1=u'B', field2=u'A', userid=u'5'),
Example(key=Key('Example', '5~X~Y'), field1=u'Y', field2=u'X', userid=u'5')
]

鉴于上述数据,我想找到以下内容: - 查找同时满足以下两个条件的所有用户 ID:

field1='B', field2='A'
and field1='D', field2='C'

在上面的示例中,以下用户标识将符合此条件:

userid='1' 
userid='2'

所以我的问题是,我们是否可以使用单个ndb查询找到上述结果?如果是这样,怎么办?

我现在知道的方法只能通过 OR ndb 查询来实现,我们在其中找到所有匹配的记录

Example.query(ndb.OR(ndb.AND(field1='B' AND field2='a'), ndb.AND(field1='D' AND field2='C')))

然后遍历结果(在python中(,然后有一个逻辑来仅提取那些具有 字段 1='B', 字段 2='A' 和字段 1='D', 字段 2='C'

由于以下原因,这似乎不是一种有效的方法: - 我们使用 OR 组合不必要地提取超出需要的记录。 - 如果我们用fetch_page限制结果,则无法使用我们的标准过滤掉多少条记录。它甚至可能导致基于我们的限制的空记录。

或者,如果有一种方法让我首先找到字段 1='B' 和字段 2='A' 的所有用户 ID,然后直接在此结果中查询以查找字段 1='D' 和 field2='C' 的所有用户 ID,这也将解决问题。所以这是查询查询结果。

感谢您的意见/建议。谢谢。

是的,ndb.OR运算效率不高,可能会导致组合爆炸,请参阅组合 AND 和 OR 运算中的讨论。

另请记住,您查询的是Example元素,而不是用户 ID。这意味着您无法在field1='B' and field2='A'查询的结果中真正查询field1='D' and field2='C'- 结果将始终为空,因为field1不能同时'D''B'

因此,您确实需要执行单独的 2 个查询,提取每个结果中的用户 ID 集,然后检查 2 个集合的交集。

可以使用不同的投影查询(实验性!(来更有效地获取用户列表:

query_1 =  Example.query(ndb.AND(Example.field1='B' AND Example.field2='A'),
projection=[Example.userid], distinct=True))
query_2 =  Example.query(ndb.AND(Example.field1='D' AND Example.field2='C'),
projection=[Example.userid], distinct=True))
users_1 = set([example.userid for example in query_1.fetch()])
users_2 = set([example.userid for example in query_2.fetch()])
users_list = list(users_1 & users_2)

注意:我实际上并没有尝试上面的代码,它仅基于文档。

最新更新