在参照此不同,但不无关系问题我将借用模型示例。

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)

如果您不应用任何不平等或排序顺序的查询,数据存储将能够执行的,无论你申请了多少过滤器使用内置的索引和合并联接策略的查询。如果你需要一个不平等或排序顺序,但是,你需要对你也许要过滤棒的每个数字,从而导致爆炸索引的索引(所以最好避免!)

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top