Google App Engine - 如何对ndb查询返回的结果执行python ndb查询?

时间:2017-07-01 20:39:38

标签: python google-app-engine app-engine-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')
]

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

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

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

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中)然后有一个逻辑来只提取那些有的用户ID              field1 =' B',field2 =' A'     和field1 =' D',field2 =' C'

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

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

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

1 个答案:

答案 0 :(得分:1)

是的,DataContext操作效率不高,可能导致组合爆炸,请参阅Combining AND and OR Operations中的讨论。

另请注意,您要查询Content元素,而不是用户ID。这意味着您无法在<CommandBar Content="{Binding OtherViewModel, Source={StaticResource Locator}}"> <CommandBar.ContentTemplate> <DataTemplate> <TextBlock Text="{Binding Status}"></TextBlock> </DataTemplate> </CommandBar.ContentTemplate> ... </CommandBar> 查询的结果中查询ndb.OR - 结果将始终为空,因为Example不能同时同时为field1='D' and field2='C'field1='B' and field2='A'

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

可能可以使用distinct projection queries(实验!)来更有效地获取用户列表:

field1

注意:我没有真正尝试上述代码,它仅基于文档。