开发者

Sorting a StringListProperty based on position of element in app engine

I have model which looks like this:

class Example (db.Model) :
 name = db.StringProperty()
 tags = db.StringListProperty()

I first query for a tag to get the list of entities which have them:

results = Example.all().filter("tags =", tagSearch).fetch(100)

This gives me a list of entities containing the "tagSearch" in their "tags" list.

Here is how a sample of the result entities would look like:

entityA = [tagSearch, m, n, o, ....]

entityB = [a, b, c, tagSearch, ... ]

entityC = [a, tagSearch, a, ,a ,x ....... ....]

I want to sort all the entities in the result set based on the position of the item tagSearch in them, in descending order.

basically - entityA, entityC, entityB 

How do I do this? note I am running this on appengine ...

also assumption given than tagSea开发者_开发技巧rch will occur only once in any list.

Any help will be highly appreciated.


The only way I can think of to do this is to modify your tag list to include positions, and use an inequality filter. For example, you could modify the tags to be of the format "tag:ordinal", where ordinal is the position in the list (entityA would thus have ["tagSearch:0", "m:1", "n:2", "o:3"]). Then, instead of doing an equality filter, you perform a query such as this one:

results = Example.all().filter("tags >=", tagSearch + u":").filter("tags <", tagSearch + u":\ufffd").fetch(100)

The result set will thus be ordered by the position the searched-for tag appears in the list. The downside is that you can now only query for a single tag at a time - multiple inequality filters aren't possible in App Engine.


You won't be able to sort these in the query, as far as I know. So the only alternative is to fetch them all and sort them accordingly in your code.

This may not be feasibly performant depending on the number of entities you'd have to return, so you may want to limit the entities in some other way before fetching.


I agree with Jason Hall that given your model it's not going to be doable with a query.

You could try changing your model to something like this:

class Example (db.Model) :
    name = db.StringProperty()

class ExampleTag(db.Model):
    example_id = db.IntegerProperty()
    tag_name = db.StringProperty()
    tag_rank = db.IntegerProperty()

Then you run your query like this:

query = ExampleTag.all()
query.filter('tag_name =', 'tagSearch')
query.order('tag_rank')
tags = query.fetch(100)

examples = Example.get_by_ids([x.example_id for x in tags])
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜