0

I'm implementing a frontpage with "hot" stories based on a certain ranking algorithm. However, I can't figure out how to pass App Engine Datastore my own sort function (like I can in Python with sort(key=ranking_function)). I want something like this:

class Story(db.Model):
    user = db.ReferenceProperty(User)
    text = db.TextProperty()
    def ranking(self):
        # my ranking function, returns an int or something
        return 1
    ranking = property(ranking_function)

So that I can later call:

Story.all().order("ranking").limit(50)

Any idea how to do this using App Engine Datastore models?

Deniss T.
  • 2,526
  • 9
  • 21
dave paola
  • 1,815
  • 3
  • 16
  • 27

2 Answers2

3

I don't think this is possible with App Engine the way you describe it, but I think it is possible to achieve what you want. You want the datastore to run your ranking function against every element in the datastore, every time you do a query. That is not very scalable, as you could have millions of entities that you want to rank.

Instead, you should just have a integer property called rank, and set it every time you update an entity. Then you can use that property in your order clause.

Peter Recore
  • 14,037
  • 4
  • 42
  • 62
2

There's no built in property that handles this, but there's a library, aetycoon, that implements DerivedProperty and other related properties that do what you want. Here's an article on how it works.

Nick Johnson
  • 100,655
  • 16
  • 128
  • 198
  • I did this and it works wonderfully. However, I'm adding alot of properties that seem to throw NotSavedErrors when I try to make a new object with some DerivedProperties. The only solution is to wrap the entire thing in a try-except. It works but it's slightly ugly. Thanks! – dave paola Feb 26 '10 at 00:27
  • Can you be more specific? What stacktrace do you get, and under what circumstances? – Nick Johnson Feb 26 '10 at 13:34