0
votes

Say I have the following model in Google App Engine's datastore:

class Post(ndb.Model):
  name = ndb.StringProperty()
  votes = ndb.IntegerPropery()

I want to first query Post to get all posts ordered by number of votes (highest to lowest) and then find the ranking/place of the Post with name "John". So if the Post by John has the 2nd most votes, he would be in 2nd place.

Is there an easy way to do this? Right now I'm doing something like:

posts = Post.query().order(-Post.votes)
for post, index in enumerate(posts):
  if post.name == "John":
     print(index)

I imagine this is not a very good/efficient way to do this.

1

1 Answers

0
votes

If the total number of posts is very high and those named John are few it might be more efficient to do something like this:

total_posts = len(Post.query().fetch(keys_only=True))

john_posts = Post.query(Post.name == 'John')
for post in john_posts:
    # find out how many posts have higher votes than this post
    rank = len(Post.query(Post.votes > post.votes).fetch(keys_only=True))
    print('%d out of %d' % (rank, total_posts))

It will also be cheaper, since you'd be reading from the DB only John-named posts (paid DB ops) - keys_only queries are free.

It's not an actual index in the total list though - you'd get same rank for posts with the same number of votes.