Frage

In Bezug auf diese verschiedene, aber nicht unabhängig Frage werde ich leihen, um die Beispielmodelle.

class Foo(db.Model): bars = db.ListProperty(db.Key)

class Bar(db.Model): pass

Wenn ich eine bestimmte Foo Einheit haben und ich möchte alle anderen foo Einheiten erhalten auch eine bestimmte Bar Key in seinen Bars Listproperty enthält, würde ich die folgende Abfrage verwenden:

related_foos = Foo.all().filter('bars', bar_entity).fetch(fetch_count) 

Was ist, wenn ich will alle anderen Einheiten des Modells Art Foo finden, die zumindest eine Anzahl von N Anpassungs bar Einheiten haben? Der offensichtliche Weg, dies mit einer for-Schleife zu tun drastische Ineffizienzen beinhalten würde, und es könnte am besten tatsächlich sein, um das Modell zu ändern sich diese leichter zu machen, aber es scheint nicht klar, wie dies zu tun.

War es hilfreich?

Lösung

ein foo Datensatz gegeben, die mit 10 bar_entities hat und auf der Suche für alle foo Datensätze, die mindestens zwei dieser 10 Einheiten haben 10 in 45 mögliche Gleichheit Werte ergeben würde! / (2! * (10-2)!) = 45.

Dies kann in 10_C_ abgeleitet werden (2-1) = 10 liest.

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.

Dieses Lese auf einen reduzieren würde erfordern, dass, wenn ein foo Datensatz hinzugefügt Sie eine separate Tabelle zu füllen, die für einen bestimmten Datensatz alle zwei Kombinationen hatte.

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

Auf diese Weise kann in jede Explosion Index Probleme bekommen würde nicht.

Wenn Sie auch alle 3 oder 4 beliebige Einheiten tun wollte, als für jede dieser Sie eine foo_combo_n_table erstellen müssten oder eine 10_C_ tun (n-1) Anzahl der liest.

Andere Tipps

Sie können einfach die gleichen Filter anwenden wiederholt:

related_foos = Foo.all().filter('bars', bar_entity).filter('bars', bar_entity_2).fetch(fetch_count)

Oder datengetriebener:

q = Foo.all()
for bar in bar_entities:
  q.filter('bars', bar)
related_foos = q.fetch(fetch_count)

Wenn Sie gelten keine Ungleichheiten oder Sortierreihenfolgen auf die Abfrage, wird der Datenspeicher der Lage, die Abfragen auszuführen unter Verwendung der in Indizes erstellt und der Merge-Strategie verbinden, unabhängig davon, wie viele Filter, die Sie anwenden. Wenn Sie eine Ungleichheit oder Sortierreihenfolge benötigen, jedoch müssen Sie einen Index für jede Anzahl von Bars haben Sie gefiltert werden könnten wollen, was zu explodierenden Indizes (und so ist am besten vermieden werden!)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top