Appengine filter inequality and ordering fails

前端 未结 5 1572
悲哀的现实
悲哀的现实 2021-02-01 18:03

I think I\'m overlooking something simple here, I can\'t imagine this is impossible to do.

I want to filter by a datetime attribute and then order the result by a rankin

相关标签:
5条回答
  • 2021-02-01 18:37

    The Datastore has some limitations on queries. One is not allowing to combine inequality filter on one property with order on anther property. You can find more restrictions here:

    https://cloud.google.com/appengine/docs/python/ndb/queries

    0 讨论(0)
  • 2021-02-01 18:38

    I don't know since when, but current SDK may return subtle different error:

    BadArgumentError: First ordering property must be the same as inequality filter property, if specified for this query; received ranking, expected submitted
    

    In my case, I could work around the error with this:

    query.filter("submitted >=" thisweek).order("submitted").order("ranking")
    

    Edited 2013-02-08: As Horselover Fat mentioned in a comment, it only avoids an error.

    0 讨论(0)
  • 2021-02-01 18:39

    I used another trick, which worked out simply because of the format I needed my data in (a list of dicts). In this case I run the datetime-based query, create dicts from the returned ents, and then sort by the numeric 'counter' property. Reversing the sort gave me a descending order. Keep in mind I only requested 10 results, on a fairly small datastore.

    q = food.Food.all()
    q.filter("last_modified <=", now)
    q.filter("last_modified >=", hour_ago)
    
    ents = q.fetch(10)
    
    if ents:
      results = [{
        "name": ent.name,
        "counter": ent.counter
        } for ent in ents]
    
      # reverse list for 'descending' order
      results.sort(reverse=True)
    

    Example result:

    [{'counter': 111L, 'name': u'wasabi'}, {'counter': 51L, 'name': u'honeydew'}, {'counter': 43L, 'name': u'mars bar'}, {'counter': 37L, 'name': u'scallop'}, {'counter': 33L, 'name': u'turnip'}, {'counter': 29L, 'name': u'cornbread'}, {'counter': 16L, 'name': u'mackerel'}, {'counter': 10L, 'name': u'instant coffee'}, {'counter': 3L, 'name': u'brussel sprouts'}, {'counter': 2L, 'name': u'anchovies'}]
    
    0 讨论(0)
  • 2021-02-01 18:42

    The datastore isn't capable of ordering a query that contains an inequality by any property other than the one used in the inequality.

    This can often be worked around by adding a property that can be filtered with an equality; in this case, it may be possible to have a BooleanProperty tracking whether an entity is from the current week, and update it for all entities at the end of each week.

    0 讨论(0)
  • 2021-02-01 18:46

    The simplest way would be to split your query:

    q1 = query.filter("submitted >=" thisweek)
    q2 = q1.order("ranking")
    
    0 讨论(0)
提交回复
热议问题