Re: ListProperty costs

33 views
Skip to first unread message

Jason Collins

unread,
Nov 5, 2012, 10:21:51 PM11/5/12
to google-a...@googlegroups.com
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
Reply all
Reply to author
Forward
0 new messages