Domanda

In riferimento a questa domanda diversa, ma non estraneo lo farò prendere in prestito i modelli di esempio.

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

class Bar(db.Model): pass

Se ho una certa entità Foo e voglio ottenere tutte le altre entità Foo contenenti anche un certo bar Digitare i suoi bar ListProperty, vorrei utilizzare la seguente query:

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

Che dire se voglio trovare tutte le altre entità del modello tipo Foo che hanno almeno un numero N di corrispondenza entità a barre? Il modo più ovvio per fare questo con un ciclo for comporterebbe drastici inefficienze, e potrebbe essere meglio per cambiare realmente il modello stesso per rendere questo più facile, ma non sembra ovvio come farlo.

È stato utile?

Soluzione

Dato un record foo che ha 10 bar_entities e alla ricerca di tutti i record Foo che hanno almeno 2 di questi 10 soggetti si tradurrebbe in 45 possibili valori dell'uguaglianza 10! / (2 * (10-2)!) = 45.

Questo può essere dedotta in 10_C_ (2-1) = 10 legge.

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.

Per ridurre questo ad una lettura richiederebbe che, quando si aggiunge un record foo di popolare una tabella separata che aveva tutte le 2 combinazioni per un dato record.

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

In questo modo è solito entrare in eventuali problemi di indice che esplodono.

Se anche si voleva fare qualsiasi 3 o qualsiasi 4 soggetti che per ognuno di questi si avrebbe bisogno di creare un foo_combo_n_table o di fare un certo numero 10_C_ (n-1) della legge.

Altri suggerimenti

Si può semplicemente applicare lo stesso filtro più volte:

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

In alternativa, su dati:

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

Se non si applica alcun disuguaglianze o ordinare gli ordini alla query, il datastore sarà in grado di eseguire le query utilizzando il costruito nel indici e l'unione strategia di join, indipendentemente dal numero di filtri si applica. Se avete bisogno di un ordine disuguaglianza o di specie, tuttavia, è necessario disporre di un indice per ogni numero di barre si potrebbe desiderare di filtrare, che porta a indici di esplodere (e così è meglio evitare!)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top