The NDB Datastore forbids multiple inequality queries on different properties. To get around this, I thought that the solution might be to combine the results of multiple independent queries. I found this 2011 question which recommends geohashing, with which I am not familiar. So, perhaps there is a better solution today.
Consider these two queries:
q1 = User.query(User.age < 18).fetch()
q2 = User.query(User.city != 'New York City').fetch()
I attempt to join them like this:
results = set(q1).intersection(q2)
However, I encounter TypeError: Model is not immutable
.
My questions:
TypeError
above?Thank you for the assistance.
If you can restructure your User
model, you could put in some more properties to make the queries simpler. For example, if you query on the same age ranges, then make a property that encodes the ranges:
age_range = ndb.IntegerProperty() # 0 = 0-17, 1 = 18-29, 2 = 30-39, etc.
Then you can have:
q1 = User.query(User.age_range == 0).query(User.city != 'New York City').fetch()
If your data set is small enough, you can use @TimHoffman's approach:
q1 = User.query(User.age < 18).fetch(keys_only=True)
q2 = User.query(User.city != 'New York City').fetch(keys_only=True)
results = ndb.get_multi(set(q1).intersection(q2))
A more heavyweight approach, that will scale up to big data sets, is the MapReduce library. You can put in multiple filters to reduce your data set.