Rather than query on a cost range, is it possible to create "range buckets"?
E.g, you could have buckets defined like this:
1: < 100
2: 100 - 199.99
3: 200 - 299.99
4: 300 - 399.99
5: >= 400
Then, in your model, you'd have a ComputedProperty:
def MyModel(ndb.Model):
cost = ndb.FloatProperty(required=True)
score = ndb.IntergerProperty(required=True)
...
cost_bucket = ndb.ComputedProperty(repeated=True, name='cb', lambda entity: MyModel.compute_cost_bucket(entity), indexed=True)
@classmethod
def compute_cost_bucket(cls, entity):
if entity.cost < 100:
return ['1']
if entity.cost < 200:
return ['2']
...
Then you can query by an equality filter on your cost_bucket, but order by score:
query = MyModel.query().filter(MyModel.cost_bucket == '1').order(MyModel.score)
You can have more cost buckets yielding a longer list of values, possibly even overlapping buckets, but the key thing is that you're only ever querying on one equality filter. So, for example, you could create a bucket called '1-2' that was for <200.
Caveat: deserializing a long list from a protocol buffer can be slow; projection queries can help if it becomes a problem. Also, writing a long list of indexed values costs $$.
Finally, the name 'cb' above is just a small storage optimization because the name is repeated in the protocol buffer for each value.
j
On Monday, 5 November 2012 08:33:16 UTC-6, Guillaume wrote:
Hi all,
I want to query all entities with a property (called "cost") within a given range, and order the results according to another property (called "score"). Both are integers.
According to the doc, I cannot do that because I should order by the "cost" first...
Then I thought I could use a ListProperty of 2 elements : [cost, score].
Provided that the range of possible values do not intersect, I could filter and order the way I want.
Is it a valid approach ?
Thanks