【问题标题】:Ignore Results Outside of Distance Range忽略距离范围之外的结果
【发布时间】:2017-02-03 11:46:29
【问题描述】:

我正在使用 ElasticSearch 开发一个处理“帖子”的应用程序。我目前让它与geo_point 一起使用,以便它返回所有按与最终用户的距离排序的帖子。虽然这是可行的,但我还需要在系统的另一个方面工作。

帖子可以付费,例如,如果我要为帖子付费并选择“本地”作为区域范围,那么该帖子应该只显示给距离小于或等于 20 英里的最终用户。

我的索引上有一个名为spotlight_range 的列,如果spotlight_range = 'Local' 并且距离> 20 英里,我是否可以创建一个查询来说明忽略所有记录?我需要为几个不同的聚光灯范围这样做。例如区域可能是 100 英里或更少,等等。

我当前的查询如下所示

$params = [
    'index' => 'my_index',
    'type' => 'posts',
    'size' => 25,
    'from' => 0,
    'body' => [
        'sort' => [
            '_geo_distance' => [
                'post_location' => [
                    'lat' => '44.4759',
                    'lon' => '-73.2121'
                ],
                'order' => 'asc',
                'unit' => 'mi'
            ]
        ],
        'query' => [
            'filtered' => [
                'query' => [
                    'match_all' => []
                ],
                'filter' => [
                    'geo_distance' => [
                        'distance' => '100mi',
                        'post_location' => [
                            'lat' => '44.4759',
                            'lon' => '-73.2121'
                        ]
                    ]
                ]
            ]
        ]
    ]
];

我的索引设置有以下字段。

'id' => ['type' => 'integer'],
'title' => ['type' => 'string'],
'description' => ['type' => 'string'],
'price' => ['type' => 'integer'],
'shippable' => ['type' => 'boolean'],
'username' => ['type' => 'string'],
'post_location' => ['type' => 'geo_point'],
'post_location_string' => ['type' => 'string'],
'is_spotlight' => ['type' => 'boolean'],
'spotlight_range' => ['type' => 'string'],
'created_at' => ['type' => 'date', 'format' => 'yyyy-MM-dd HH:mm:ss'],
'updated_at' => ['type' => 'date', 'format' => 'yyyy-MM-dd HH:mm:ss']

我的最终目标不是专门搜索距离

我一直在网上寻找解决方案,但运气不佳。

【问题讨论】:

  • 您能否添加更多示例来解释您的用例?
  • 我没有更多可以添加的示例,但我可以尝试更好地解释。目前,我们在配置文件中有这些字符串的值,以便可以轻松更新它们。本地 = 20 英里,区域 = 200 英里,国内 = 3000 英里,全球 = 250000 英里。例如,如果我与用户 lat/lon 查询任何大于 20 英里且标记为 Local 的帖子不会显示给该特定用户,我希望他们从搜索结果中过滤掉。我知道我可以在查询 ES 后做到这一点,但我认为这不是获取我需要过滤掉的记录的最佳选择。
  • 区域性也是如此,任何距离用户纬度/经度位置 > 200 英里的帖子都应从结果中过滤掉。我只是不确定如何将其转换为 ES 查询,而且我在 Google 或我浏览过的任何 ES 书籍中都找不到关于这个主题的内容。

标签: elasticsearch


【解决方案1】:

我会在文档中添加一个圆圈geo_shape,以post_location 为中心,半径对应于spotlight_range,因为您在索引时知道这两个信息。这样,您可以将其相应的“范围”编码到每个帖子中。

...
'post_location' => ['type' => 'geo_point'],
'spotlight_range' => ['type' => 'string'],
'reach' => ['type' => 'geo_shape'],            <---- add this

所以一个“本地”文档一旦被索引就会看起来像这样

{
    "spotlight_range": "local",
    "post_location": { 
         "lat": 42.1526,
         "lon": -71.7378
    }, 
    "reach" : {
        "type" : "circle",
        "coordinates" : [-71.7378, 42.1526],
        "radius" : "20mi"
    }
}

然后,查询将以用户位置为中心并具有所选半径的另一个 geo_shape 为特征,并且只会检索其 reach 与查询中的圆形相交的文档。

$params = [
    'index' => 'my_index',
    'type' => 'posts',
    'size' => 25,
    'from' => 0,
    'body' => [
        'sort' => [
            '_geo_distance' => [
                'post_location' => [
                    'lat' => '44.4759',
                    'lon' => '-73.2121'
                ],
                'order' => 'asc',
                'unit' => 'mi'
            ]
        ],
        'query' => [
            'filtered' => [
                'query' => [
                    'match_all' => []
                ],
                'filter' => [
                    'geo_shape' => [
                        'reach' => [
                           'relation' => 'INTERSECTS',
                           'shape' => [
                               'type' => 'circle',
                               'coordinates' => [-73.2121, 44.4759],
                               'radius' => '20mi'
                           ]
                        ]
                    ]
                ]
            ]
        ]
    ]
];

【讨论】:

  • 在您的示例中,实际查询将使用用户 lat/lon 而不是 post lat/lon 是否正确?我稍后会给出这个例子,如果它有效,我会接受你的回答。
  • 是的,在查询中您使用用户的纬度/经度,这将与以每个帖子的纬度/经度为中心的形状相匹配
  • 查看这个我不确定这是否可行,但我还没有尝试过。但是本地可能限制为 20 英里,但区域限制为 200 英里,然后是国家和世界。世界显然没有限制,但我需要过滤掉本地、国家、地区的超限,而不仅仅是一个距离限制......
  • 据我了解您的用例,这应该可以解决。告诉我
  • 那么,这个运气不好?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-01
  • 1970-01-01
  • 2021-09-02
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
  • 2017-09-26
相关资源
最近更新 更多