google-app-engine - 如何使用 Google App Engine Search API 找到最接近的文档?

标签 google-app-engine python-2.7 gae-search

我在 GAE Search 中有大约 400,000 个文档指数。所有文档都有一个 location GeoPoint 属性,并且分布在整个地球上。一些文档可能与任何其他文档相距超过 4000 公里,其他文档可能彼此相距不到几米。

我想找到最接近一组特定坐标的文档,但发现以下代码给出了不正确的结果:

from google.appengine.api import search

# coords are in the form of a tuple e.g. (50.123, 1.123)
search.Document(
    doc_id='meaningful-unique-id',
    fields=[search.GeoField(name='location' 
                            value=search.GeoPoint(coords[0], coords[1]))])

# find document function radius is in metres
def find_document(coords, radius=1000000):
    sort_expr = search.SortExpression(
        expression='distance(location, geopoint(%.3f, %.3f))' % coords,
        direction=search.SortExpression.ASCENDING,
        default_value=0)

    search_query = search.Query(
        query_string='distance(location, geopoint(%.3f, %.3f)) < %d' \
                    % (coords[0], coords[1], radius),
        options=search.QueryOptions(
            limit=1,
            ids_only=True,
            sort_options=search.SortOptions(expressions=[sort_expr])))

    index = search.Index(name='document-index')
    return index.search(search_query)

使用这段代码,我将得到一致但不正确的结果。例如,搜索距离伦敦最近的文件表明最近的文件在苏格兰。我已经验证了有数千个更接近的文件。

我将问题缩小到 radius 参数太大。如果半径降至 12 公里左右 (radius=12000),我会得到正确的结果。 12公里半径范围内一般不超过1000份文件。 (可能与 search.SortOptions(limit=1000) 有关。)

问题是,如果我在地球上数千英里内没有任何文档的稀疏区域,我的搜索函数将不会返回任何 radius=12000(12 公里) .无论我身在何处,我都希望它能将最近的文档返回给我。我如何才能通过一次调用搜索 API 来始终如一地完成这一任务?

最佳答案

我认为问题如下。 您的查询将选择最多 10K 个文档,然后根据您的距离排序表达式对这些文档进行排序并返回。 (也就是说,排序实际上并没有遍历所有 400k 文档。) 所以我怀疑一些地理上比较近的点没有包含在这个10k的选择中。 这就是为什么缩小搜索半径时效果会更好,因为该半径内的总点数较少。

从本质上讲,您希望以一种对您查询的内容有意义的方式将您的查询“点击率”降低到 10k。 您至少可以通过多种方式解决这个问题,您可以将这些方式结合起来:

  • 添加一个排名,以便按排名顺序返回最“重要”的文档(根据一些在您的域中有意义的标准),然后这些文档将按距离排序。
  • 过滤一个或多个文档字段(例如,“业务类别”,如果您的文档包含有关业务的信息)以减少候选文档的数量。

(我不认为这个 10k 阈值目前在搜索 API 文档中;我已经提交了一张票来添加它)。

关于google-app-engine - 如何使用 Google App Engine Search API 找到最接近的文档?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15254983/

相关文章:

python - 如何高效地将C/C++逻辑转换成python?

python-2.7 - Python2 在位操作方面遇到问题

gae-search - GAE 后端进程终止,因为它无法响应 HTTP 状态代码为 200-299 或 404 的启动请求

google-app-engine - 如何使用 GAE 获取 Search API 中的所有记录 ID

google-app-engine - 具有事务的分布式存储

google-app-engine - Objectify4 使用列表条件查询列表属性

java - 全文搜索是否支持无模式索引?

python - 读入 python 后从文本文件中删除第一行标题

java - 同步 Android sqlite 数据库和 GAE 数据存储