概述
Fess 可以对具有经纬度位置信息的文档执行指定地理范围的搜索。 使用此功能可以搜索距离特定地点一定距离内的文档, 或构建与 Google 地图等地图服务集成的搜索系统。
在内部,使用 OpenSearch 的 geo-distance 查询,对存在于指定中心点 指定距离以内的文档进行筛选。
用例
位置信息搜索可用于以下用途。
店铺搜索: 搜索距用户当前位置较近的店铺
房地产搜索: 搜索距特定车站或设施一定距离内的房产
活动搜索: 搜索指定地点周边的活动信息
设施搜索: 搜索旅游景点或公共设施附近
配置方法
索引生成时的配置
位置信息字段定义
在 Fess 中,``location`` 作为存储位置信息的字段已标准定义。 此字段被配置为 OpenSearch 的 geo_point 类型。
位置信息注册格式
索引生成时,将纬度和经度用逗号分隔设置到 location 字段中。
格式:
示例:
Note
纬度范围为 -90 到 90,经度范围为 -180 到 180。
数据存储爬取的配置示例
使用数据存储爬取时,从具有位置信息的数据源将经纬度设置到 location 字段。
示例: 从数据库获取
如果纬度和经度分别保存在不同的列中,请在 SQL 中将其拼接为逗号分隔的字符串。
在数据存储配置脚本中,将获取到的值映射到 location 字段。
通过脚本添加位置信息
也可以使用爬取配置的脚本功能(Groovy)动态向文档添加位置信息。 直接向字段名赋值即可。
有关脚本的详细信息,请参阅 Groovy脚本指南。
搜索时的配置
要执行位置信息搜索,需在请求参数中指定搜索中心点和范围。
请求参数
位置信息搜索的参数名格式为 geo.<字段名>.point 和 geo.<字段名>.distance。 <字段名> 处填写通过 query.geo.fields 配置的字段名 (默认为 location)。
| 参数名 | 说明 |
|---|---|
geo.location.point | 搜索中心地点的纬度·经度(逗号分隔。示例: 35.681236,139.767125 ) |
geo.location.distance | 距中心点的搜索半径(带单位。示例: 10km ) |
Note
point 和 distance 须成对指定。未指定 distance 的 point 将被忽略。 此外, point 的值必须由”纬度,经度”两个数值组成,格式不正确时将报错。
Note
对同一字段指定多个 point 时为 OR 条件(位于任一范围内), 对多个字段分别指定时为 AND 条件(同时位于所有范围内)。
距离单位
距离可使用以下单位。
km: 千米m: 米mi: 英里yd: 码
Note
距离值将直接传递给 OpenSearch,因此除上述单位外,还可使用 OpenSearch 支持的其他单位 ( cm 、 mm 、 ft 、 in 、 nmi 等)。
搜索结果的排序顺序
位置信息搜索作为 过滤器 运行,将结果限定为指定范围内的文档。 它不影响搜索评分(相关度),也不会按距中心点的远近进行排序。 结果将按常规方式以相关度顺序(或 sort 参数指定的顺序)返回。
Note
Fess 不支持按距离排序(按由近到远排列)。 如需按距离顺序显示,请在客户端根据响应中包含的经纬度自行排序。
搜索示例
基本搜索
搜索东京站(35.681236, 139.767125)半径 10km 内的文档:
当前位置周边搜索
搜索距用户当前位置 1km 内的内容:
通过 API 使用
v2 JSON 搜索 API( /api/v2/search )同样支持位置信息搜索。 将 geo.location.point 和 geo.location.distance 作为请求参数指定即可。
搜索结果通过公共信封的 response.data 数组返回。API 的详细信息请参阅 搜索 API 和 API 概述。
Note
location 字段默认不包含在 API 响应中。如需在搜索结果中包含经纬度, 请在 fess_config.properties 中添加以下配置。
字段名自定义
更改默认字段名
要更改位置信息搜索使用的字段名, 请在 fess_config.properties 中修改以下配置。
指定多个字段名时,请用逗号分隔。
Note
请求参数名与所配置的字段名联动。例如,设置
query.geo.fields=coordinates时,需指定geo.coordinates.point和geo.coordinates.distance。此处指定的各字段必须在索引映射中定义为
geo_point类型。
实现示例
Web 应用程序实现
JavaScript 获取当前位置并执行搜索的示例:
Google 地图集成
在 Google 地图上用标记显示搜索结果的示例:
Note
此示例从搜索结果中引用 location 字段。需要事先设置 query.additional.api.response.fields=location,以便在响应中包含经纬度。
性能优化
确认索引设置
位置信息字段在安装目录的 app/WEB-INF/classes/fess_indices/fess/doc.json 中定义为 geo_point 类型。
geo_point 类型的字段使用 BKD 树进行索引,因此 geo-distance 查询可高效执行。
搜索范围和响应的优化
增大搜索半径时,范围内匹配的文档数量会增加,获取和渲染结果可能需要更长时间。
请根据用途设置适当的搜索半径。
在地图显示等需要处理大量结果的场景中,请调整页面大小(
num参数)以限制获取数量。
故障排除
位置信息搜索无法工作
请确认
location字段中是否正确存储了数据。请确认纬度经度格式是否正确(
纬度,经度逗号分隔。值不为两个时将报错)。请确认 OpenSearch 的索引映射中
location是否定义为geo_point类型。请确认是否同时指定了
point和distance``(未指定 ``distance的point将被忽略)。
搜索结果未返回
请确认指定距离范围内是否存在文档。
请确认纬度经度值是否在正确范围内(纬度: -90〜90, 经度: -180〜180)。
请确认距离单位是否正确指定。
API 响应中不包含位置信息
location 字段默认不包含在 API 响应中。 如需在搜索结果中包含经纬度,请在 fess_config.properties 中 设置 query.additional.api.response.fields=location。
位置信息未正确注册
请确认爬取时
location字段是否正确设置。请确认数据源的纬度经度是否能够正确获取。
通过脚本设置位置信息时,请确认是否为
纬度,经度的字符串格式。
参考信息
有关位置信息搜索的详细信息,请参考以下资源。