Google App Engine-如何对NDB查询返回的结果进行python NDB查询? [英] Google App Engine - How could I do python ndb query on results returned by a ndb query?
问题描述
我正在为一个项目使用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中),然后具有仅提取具有以下内容的用户ID的逻辑: field1 ='B',field2 ='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
操作不是非常有效,并且可能导致组合爆炸,请参见
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' and field2='A'
查询的结果中查询field1='D' and 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集,然后检查2个集的交集.
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屋!