Reputation: 3634
I'm coming from a SQL background, and I'm wondering how do to filters in NDB that would be the equivalent of many joins in SQL, and how to make these queries scale. As an example:
class PromDate(ndb.Model):
user_id = ndb.StringProperty(required=True) # user id
age = ndb.IntegerProperty()
class DesignerBrand(ndb.Model):
name = ndb.StringProperty()
class Socks(ndb.Model):
owner = ndb.KeyProperty(kind=PromDate, required=True) # reference to PromDate
designer = ndb.KeyProperty(kind=DesignerBrand, required=True) # reference to DesignerBrand
color = ndb.StringProperty()
do_they_smell = ndb.BooleanProperty()
class Tie(ndb.Model):
owner = ndb.KeyProperty(kind=PromDate, required=True) # reference to PromDate
designer = ndb.KeyProperty(kind=DesignerBrand, required=True) # reference to DesignerBrand
color = ndb.StringProperty()
If we want to find a PromDate over 21 that owns blue Calvin Klein or Target socks that don't smell and a red tie, how do we best do this without using StructuredProperties? An example query would be extremely helpful.
What are the tradeoffs between using associations with keys like above and putting the Socks/Tie as a repeated StructuredProperty of the PromDate? Specifically, I am worried about size limitations (1MB, according to the docs) if we add tons of other clothing items (e.g., hundreds of thousands) to our PromDate.
Basically, how should we think about complex queries like this in NDB? How do we keep them fast and simple - and, most importantly, scalable at high volumes of data?
Upvotes: 0
Views: 457
Reputation: 462
You can denormalize your data and form a Structured property, then run multiple filters on it.
From their samples:
class Address(ndb.Model):
type = ndb.StringProperty() # E.g., 'home', 'work'
street = ndb.StringProperty()
city = ndb.StringProperty()
class Contact(ndb.Model):
name = ndb.StringProperty()
addresses = ndb.StructuredProperty(Address, repeated=True)
def query_contact_multiple_values_in_single_sub_entity():
query = Contact.query(Contact.addresses == Address(city='San Francisco',
street='Spear St'))
return query
Upvotes: 1
Reputation: 881705
Unfortunately, I believe you will need several queries to whittle down the list of PromDate
instances you require.
That's NoSQL for you: the more carefully you normalize your schema, the worse things can be, because, you see, no joins!
De-normalizing (with structured properties sometimes, more simply at other times -- e.g just use the designer name in lieu of a designer key so you can query on it directly) will help a bit, but, it's still a very different world from relational DBs (which is why relational DBs are still offered, e.g Google Cloud SQL, as alternatives).
Upvotes: 1