GAE Search API raising Default text value is not appropriate for sort expression

151 views Asked by At

I am doing a location search in Google App Engine and I want my search to be sorted based on proximity. I am getting the following error on the deployed version (production):

Search error:
Traceback (most recent call last):
  File "/base/data/home/apps/s~sound-helper-87921/1.385231928987755902/application/search_handler.py", line 68, in doProductSearch
    search_results = docs.Product.getIndex().search(search_query)
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/datastore/datastore_rpc.py", line 105, in positional_wrapper
    return wrapped(*args, **kwds)
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/search/search.py", line 3676, in search
    return self.search_async(query, deadline=deadline, **kwargs).get_result()
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/search/search.py", line 262, in get_result
    return self._get_result_hook()
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/search/search.py", line 3690, in hook
    _CheckStatus(response.status())
  File "/base/data/home/runtimes/python27/python27_lib/versions/1/google/appengine/api/search/search.py", line 517, in _CheckStatus
    raise _ERROR_MAP[status.code()](status.error_detail())
InvalidRequest: Failed to parse search request "distance(location, geopoint(30.008164999999998,-95.52959159999999)) < 2000"; Default text value is not appropriate for sort expression 'distance(location, geopoint(30.008165,-95.529592))'

The following is my code, which is pretty much copied from Google's tutorial:

  def _buildQueryString(self, params):
      userstr = string = params.get('querystr')
      userprice = params.get('price')
      userdist = params.get('less_than_distance')
      loc = params.get('cur_location')
      lat = loc.split(',')[0].split()[0]
      lng = loc.split(',')[1].split()[0]

      if userstr:
          string = userstr
      if userprice:
          string = string + ' price < %s' % userprice
      if userdist:
          if not os.environ.get('SERVER_SOFTWARE','').startswith('Development'):

              string = string + ' distance(%s, geopoint(%s,%s)) < %s' % (
                                        docs.Product.LOCATION,lat,lng,userdist)

      return string

  def _buildQuery(self, params):
    """Build and return a search query object."""
    user_query = self._buildQueryString(params)
    doc_limit = self._getDocLimit()

    try:
      offsetval = int(params.get('offset', 0))
    except ValueError:
      offsetval = 0
    loc = params.get('cur_location')
    lat = loc.split(',')[0].split()[0]
    lng = loc.split(',')[1].split()[0]
    expr = 'distance(%s, geopoint(%f,%f))' % (docs.Product.LOCATION,float(lat),float(lng))
    computed_expr_distance = search.FieldExpression(name='actual_distance',
       expression=expr)
    computed_expr_score = search.FieldExpression(name='actual_score',
       expression='score')
    returned_fields = [docs.Product.PID]
    expr_list = []
    expr_list.append(search.SortExpression(
       expression=expr,
       direction=search.SortExpression.ASCENDING,
       default_value='2001'))
    sortopts = search.SortOptions(expressions=expr_list, limit = doc_limit)
    search_query = search.Query(
                    query_string=user_query.strip(),
                    options=search.QueryOptions(
                        limit=doc_limit, 
                        offset=offsetval,
                        sort_options=sortopts,
                        returned_expressions=[computed_expr_distance],
                        returned_fields=returned_fields
                    )
                   )
    return search_query

  def doProductSearch(self, params):
    """Perform a product search and display the results."""

    try:
      search_query = self._buildQuery(params)
      search_results = docs.Product.getIndex().search(search_query)
      returned_count = len(search_results.results)

    except search.Error:
      logging.exception("Search error:")
      msg = 'There was a search error (see logs).'
      url = '/'
      print('%s' % msg)
      return [],[]

    psearch_response = []
    distances = []
    # For each document returned from the search
    for doc in search_results:
        pdoc = docs.Product(doc)
        for expr in doc.expressions:
            if expr.name == 'actual_distance':
                distances.append(expr.value)

        pid = pdoc.getPID()
        psearch_response.append(long(pid))
    logging.debug('Distances: ' +str(distances))
    return psearch_response, distances

Why is the Search API not recognizing my search query?

1

There are 1 answers

0
Manuel Godoy On BEST ANSWER

The problem was in my default_value. I modified the SortExpression to have an integer default_value instead of a string:

expr_list.append(search.SortExpression(
   expression=expr,
   direction=search.SortExpression.ASCENDING,
   default_value=500000))