最有效的方法在db.Model的ListProperty符合特定数量的项目
-
20-09-2019 - |
题
在参照此不同,但不无关系问题我将借用模型示例。
class Foo(db.Model): bars = db.ListProperty(db.Key)
class Bar(db.Model): pass
如果我有一定的富实体和我想要得到所有其他的富实体也包含在其酒吧某条关键的的ListProperty,我会用下面的查询:
related_foos = Foo.all().filter('bars', bar_entity).fetch(fetch_count)
样,如果我想找到至少有N多条匹配的实体模型样美孚的所有其他实体是什么?最明显的方式做到这一点有一个for循环将涉及激烈的效率低下,这可能是最好的实际更改模型本身,使这个更容易,但它似乎并不明显怎么做。
解决方案
鉴于具有10个bar_entities一个Foo记录并寻找具有这些10个实体中的至少2将导致45可以平等的所有富记录值10!/(2!*(10-2)!)= 45。
这可以在10_C_推断(2-1)= 10读取。
SELECT * from table WHERE bar="1" AND bar in ["2", "3", "4", "5", "6", "7", "8", "9", "0"]
SELECT * from table WHERE bar="2" AND bar in ["3", "4", "5", "6", "7", "8", "9", "0"]
SELECT * from table WHERE bar="3" AND bar in ["4", "5", "6", "7", "8", "9", "0"]
etc.
要减少这种对一个读取将需要的是,当添加foo的记录可以填充一个单独的表中的是把所有的2个组合为一个给定的记录。
Say you had
foo_table
foo1 [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
foo2 [1, 3, 4]
foo3 [1, 2, a]
foo4 [b, 6, c]
foo_combo_2_table
Parent Combination
foo1 12
foo1 13
... and all 45 foo1 combinations each in its own row
foo2 13
foo2 14
foo2 34
foo3 12
foo3 1a
foo3 2a
etc.
Now you can do a
indexes = SELECT __KEY__ from foo_combo_2_table WHERE combination IN [12, 13, 14, 15, ... all 45]
keys = [k.parent() for k in indexes] # you would need to filter for duplicates
这样,你不会得到任何进入爆炸指数的问题。
如果您还希望做任何3个或4个任何实体不是为每个这些你将需要创建一个foo_combo_n_table或做10_C_第(n-1)个的读取。
其他提示
可以简单地反复应用相同的过滤器:
related_foos = Foo.all().filter('bars', bar_entity).filter('bars', bar_entity_2).fetch(fetch_count)
或者,数据驱动:
q = Foo.all()
for bar in bar_entities:
q.filter('bars', bar)
related_foos = q.fetch(fetch_count)
如果您不应用任何不平等或排序顺序的查询,数据存储将能够执行的,无论你申请了多少过滤器使用内置的索引和合并联接策略的查询。如果你需要一个不平等或排序顺序,但是,你需要对你也许要过滤棒的每个数字,从而导致爆炸索引的索引(所以最好避免!)
不隶属于 StackOverflow