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

查看:101
本文介绍了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中),然后具有仅提取具有以下内容的用户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屋!

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