Google App Engine - 如何对 ndb 查询返回的结果执行 python ndb 查询? [英] Google App Engine - How could I do python ndb query on results returned by a ndb query?

查看:36
本文介绍了Google App Engine - 如何对 ndb 查询返回的结果执行 python ndb 查询?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am using GAE python (webapp2) framework for a project and have a question related to ndb query. Let me give an example to explain this clearly:

这是我拥有的 ndb 模型:

Here is a ndb model I have:

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

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

Here are the entities I have created using the above model:

[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:

Given the above data I want to find the following: - Find all userids which have both of the following conditions met:

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

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

In the above example the following userids will match this criteria:

userid='1' 
userid='2'

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

So the question I have is, Is it possible for us to find the above result using a single ndb query? If so how?

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

The method I know right now to do this can only be achieved with a OR ndb query where we find all records matching

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

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

Then iterate through the results (in python) and then have a logic to extract only those userids which have field1='B', field2='A' and field1='D', field2='C'

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

This doesn't seem to be an efficient way because of the following reason: - We are unnecessarily extracting more than needed records with the OR combination. - If we limit the results with fetch_page, there is no way to know how many records will be filtered out using our criteria. It could even result in empty records based on our limit.

或者,如果有办法让我首先找到 field1='B' 和 field2='A' 的所有用户 ID,然后直接在此结果中查询以找到所有带有 field1='D' 和 field2='C 的用户 ID'这样也能解决问题.所以这是对查询结果的查询.

OR if there is a way for me to first find all userids with field1='B' and field2='A' and then directly query within this result to find all userids with field1='D' and field2='C' that will also solve the problem. So this is querying over a query result.

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

Appreciate your inputs / suggestions. Thanks.

推荐答案

是的,ndb.OR 操作效率不高,会导致组合爆炸,见结合 AND 和 OR 操作.

Yes, the ndb.OR operation is not very efficient and can cause combinatorial explosion, see the discussion in Combining AND and OR Operations.

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

Also keep in mind that you're querying for Example elements, not for userids. Which means you can't really query for field1='D' and field2='C' within the results for the field1='B' and field2='A' query - the result will always be empty because field1 cannot simultaneously be both 'D' and 'B'.

所以你真的需要做单独的 2 个查询,提取每个结果中的用户 ID 集合,然后检查这两个集合的交集.

So you really need to do separate 2 queries, extract the sets of userids in each of the results and then check for the intersection of the 2 sets.

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

It might be possible to use distinct projection queries (experimental!) to get the list of users more efficiently:

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)

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

Note: I didn't actually try the above code, it's based only on the documentation.

这篇关于Google App Engine - 如何对 ndb 查询返回的结果执行 python ndb 查询?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆