Domanda

Qual è la migliore pratica per il filtraggio basato sulla proprietà di una chiave esterna in un database non relazionale? Mi rendo conto che la mancanza di sostegno join rende le cose più complicate, e quindi mi chiedevo come gli altri hanno ottenuto intorno ad esso.

Nel mio caso, ho eventi, che appartengono a siti, che appartengono alle regioni. Voglio filtrare tutti gli eventi in una data regione. Un Event ha una proprietà site che è una chiave esterna a una Site, che a sua volta ha una chiave esterna region ad un Region:

region = Region.objects.get(id=regionID)
events = Event.objects.filter(site__region=region)

Questo non funziona, perché site__region richiede un join e che non è supportato su django-nonrel in esecuzione su Google App Engine. (Ricevo Caught DatabaseError while rendering: This query is not supported by the database. come un errore.) Sono stato così iterazione attraverso eventi, aggiungendo quelli che corrispondono a un elenco:

events = list()
region = Region.objects.get(id=regionID)
for event in Event.object.all():
    if event.site.region==region:
        events.append(event)

E 'questo un buon modo di fare le cose? C'è qualcosa di stupido che ho trascurato? Grazie in anticipo!

È stato utile?

Soluzione

Questa è una soluzione molto inefficiente perché si dereference sito e della regione, causando un sacco di domande. Questo non scala al di là forse 100 eventi nel vostro DB.

La soluzione migliore è quella di denormalizzare dati copiando per esempio id della regione in Event su Save (). Poi si può fare direttamente Event.objects.filter (region_id = regionId). Il codice risultante diventa meno pulita e gestibile, ma questo è il modo in cui funzionano le cose su DB non relazionali, oggi .

tutto quello che posso dire ora è: aspettare fino alla fine del mese di gennaio, se potete. ;)

Altri suggerimenti

Gennaio è andato e ora supporta dbindexer semplice join. È possibile leggere qui: http : //www.allbuttonspressed.com/blog/django/joins-for-nosql-databases-via-django-dbindexer-first-steps

Se si sta già utilizzando dbindexer si dovrebbe semplicemente registrare il proprio indice utilizzando qualcosa di simile:

# photo/dbindexes.py:

from models import Event
from dbindexer.lookups import StandardLookup
from dbindexer.api import register_index

register_index(Event, {'site__region': StandardLookup(),})
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top