Solr 空间搜索配置、按经纬度计算距离排序
Solr 空间搜索配置 1. 在solr目录下的找到conf文件夹下的schema.xml. <fields> <!-- 在fields元素中添加如下代码 --> <field name="store_lat_lon" type="location" indexed="true" stored="true"/> <dynamicField name="*_coordinate" type="double" indexed="true" stored="false" multiValued="false"/> </fields> 2. 在solr目录下的找到conf文件夹下的db-data.config.xml . 把dataConfig标签内的script标签的内容做如下修改。 <script><![CDATA[ function f1(row){ row.put('$docBoost', 1); var lat_coordinate = row.get("GPS_Y "); var log_coordinate = row.get("GPS_X "); if( lat_coordinate != null && log_coordinate != null ){ if( lat_coordinate*1 >= -90 && lat_coordinate*1 <= 90 ) { var store_lat_lon = lat_coordinate + "," + log_coordinate; var arr = new java.util.ArrayList() arr.add(lat_coordinate); arr.add(log_coordinate); row.put("store_lat_lon",store_lat_lon); row.put("item",arr); } } return row; } ]]></script> 3. 重新启动solr. 重建索引:http://localhost:8080/solr/dataimport?command=full-import 4. 查询示例: http://localhost:8080/solr/select/?q=*:*&fq={!geofilt}&sfield=store_lat_lon&pt=86.13909901,41.770741&d=5&fl=name,gps_x,gps_y,store_lat_lon&sort=geodist() asc 参数 描述 示例 d 距离(单位:km) &d=10.0 pt 搜索过滤的中心点,纬度,经度坐标点 &pt=33.4,29.0 sfield 空间搜索类型的字段(eg: solr.LatLonType) &sfield=store_lat_lon fq 设置查询过滤器 fq={!geofilt} sort 根据字段或者函数排序 &sort=geodist() asc geofilt 函数: 使结果集约束在到中心点位置的最大距离(km)圆形区域内。 geodist 函数: 计算两点之间的距离。 注意:solr 3.4版本以上才支持geodist等空间搜索函数。 参考:http://wiki.apache.org/solr/SpatialSearch Script形式的转换只在JDK1.6版本或以上才支持,下面是通用的空间搜索转换的实现,支持JDK1.5及其以上版本。 新建一个类如下所示,该类可以不继承或实现任何其他接口或者抽象类,但是transformRow方法必须定义成下面所示,SOLR dataimport插件会通过反射的方式去调用这个方法。 package com.besttone.transformer; import java.util.ArrayList; import java.util.Map; public class LocationTransformer { // 参考资料 http://wiki.apache.org/solr/DIHCustomTransformer public Object transformRow(Map<String, Object> row) { // TODO Auto-generated method stub row.put("$docBoost", 1); Object lat_coordinate = row.get("GPS_Y"); Object log_coordinate = row.get("GPS_X"); if (lat_coordinate != null && log_coordinate != null) { if (Double.parseDouble(lat_coordinate.toString()) * 1 >= -90 && Double.parseDouble(lat_coordinate.toString()) * 1 <= 90) { String store_lat_lon = lat_coordinate.toString() + "," + log_coordinate.toString(); ArrayList arr = new ArrayList(); arr.add(lat_coordinate); arr.add(log_coordinate); row.put("store_lat_lon", store_lat_lon); row.put("item", arr); } } return row; } } 第二步在db-data-config.xml中的entity节点上配置转换类: <entity name="zbs" transformer="com.besttone.transformer.LocationTransformer" ……….. 这个类必须以全路径配置。 第三步将上面的类用jdk1.5编译并打成JAR包,放在solr/home的lib下面,然后再solr.xml中配置全局共享lib: <solr persistent="false" sharedLib="lib"> 这样dataimport就能找到这个转换类,并通过反射的方式调用transformRow实现转换. 也可以继承Transformer抽象类来实现更高级的自定义转换类应用。 参考资料 http://wiki.apache.org/solr/DIHCustomTransformer 若要返回距离,4.0版本可以参照第一种方法,4.0以下版本可参照下面第二种方法,score返回的就是距离。 Returning the distance <!>Solr4.0 You can use the pseudo-field feature to return the distance along with the stored fields of each document by addingfl=geodist() to the request. Use an alias like fl=_dist_:geodist() to make the distance come back in the_dist_ pseudo-field instead. Here is an example of sorting by distance ascending and returning the distance for each document in_dist_. ...&q=*:*&sfield=store&pt=45.15,-93.85&sort=geodist() asc&fl=_dist_:geodist() As a temporary workaround for older Solr versions, it's possible to obtain distances by using geodist or geofilt as the only scoring part of the main query. ...&sfield=store&pt=45.15,-93.85&sort=score%20asc&q={!func}geodist() 若要显示距离并按某些字段比如名字来查询的话,那查询条件只能写在fq中,如果写在q中则会影响得分,导致score字段返回的不是距离,写法如下: http://localhost:8089/solr/select/?q={!func}geodist()&fq={!geofilt}&fq=address:兴华南街&sfield=store_lat_lon&pt=41.78101895,123.36067849&d=5&sort=score%20asc&fl=score 查找5公里范围内并且地址在兴华南街的数据(fq=address:兴华南街)。
Solr 空间搜索配置、按经纬度计算距离排序的更多相关文章
- mysql使用sql语句根据经纬度计算距离排序
CREATE TABLE `locationpoint` ( `id` int(11) NOT NULL, `province` varchar(20) NOT NULL, `city` varcha ...
- iOS根据2个经纬度计算距离
#pragma mark - calculate distance 根据2个经纬度计算距离 #define PI 3.14159265358979323 +(double) CalculationDi ...
- java工具类(六)根据经纬度计算距离
Java实现根据经纬度计算距离 在项目开发过程中,需要根据两地经纬度坐标计算两地间距离,所用的工具类如下: Demo1: public static double getDistatce(double ...
- python的N个小功能(文本字段对应数值,经纬度计算距离,两个时间点计算时间间隔)
案例1 >>> import pandas as pd >>> df=pd.DataFrame({'A':[1,2,3],'B':[1,2,3],'C':[1,2, ...
- php有经纬度计算距离
/** * @desc 根据两点间的经纬度计算距离 * @param float $lat 纬度值 * @param float $lng 经度值 */ function getDistanc ...
- PHP根据两点间的经纬度计算距离,php两点经纬度计算(转)
这是一个不错的示例,直接贴代码,首先要知道纬度值.经度值 /** * @desc 根据两点间的经纬度计算距离 * @param float $lat 纬度值 * @param float $lng 经 ...
- MySQL创建根据经纬度计算距离的函数
按照经纬度计算距离 日常开发中,特别是做微信项目时,经常会遇到根据用户地理位置来展示附近商家的功能,通常解决这种问题的思路是,后台设置商家的经纬度,然后再根据前台传的经纬度进行计算,具体经纬度转换以及 ...
- PHP根据两点间的经纬度计算距离
/** * 说明: 根据两点间的经纬度计算距离 * @param float $lat 纬度值 * @param float $lng 经度值 */ function getDistance($lat ...
- cesium根据经纬度计算距离
var startLatitude = 36;var startLongitude = 120; var endLatitude=34; var endLongitude=121; var start ...
随机推荐
- Guest CPU model configuration in libvirt with QEMU/KVM
每个hypervisor对于guest能看到的cpu model定义都不同,Xen 提供host pass through,所以guest能看到的cpu和host完全相同. QEMU/KVM中gues ...
- 用find命令查找最近修改过的文件
Linux的终端上,没有windows的搜索那样好用的图形界面工具,但find命令确是很强大的. 比如按名字查找一个文件,可以用 find / -name targetfilename . 唉,如果只 ...
- 剑指offer--5.变态跳台阶
WA了一次,错误数据4,输出8,怎么真么熟悉呢?改个return过了,OMG ------------------------------------------------------------- ...
- linux 缺少libxxx.a 静态链接库
首先去官方网站下载gdb的源码包,我下载的7.4.1版本的源码包,解压开来,进入到源码包的根目录下.对于一个源码包,拿到手里首先要阅读的就是README,然后看一下INSTALL文件,这个文件里编译源 ...
- SaaS模式实现架构
SaaS模式实现架构 https://blog.csdn.net/xwq911/article/details/50630266 1. 数据库层: 数据库这一层的设计模式是很清晰的,无外乎只有3种方案 ...
- [BZOJ1242]Fishing Net
dbzoj vjudge1 vjudge2 sol 给一个无向图,求判定是不是弦图. sol 还是弦图那套理论. 复杂度是\(O(n^2)\)的,因为\(m\)本质上和\(n^2\)是同级的. cod ...
- Java String Split Method
Java String.split() method 有如下几种特殊情况: 1. 分隔符出现在首尾 public static void main(String args[]) { String St ...
- Unity Shader实现描边效果
http://gad.qq.com/article/detail/28346 描边效果是游戏里面非常常用的一种效果,一般是为了凸显游戏中的某个对象,会给对象增加一个描边效果.本篇文章和大家介绍下利用S ...
- 学习动态性能表(22)V$resource_limit
学习动态性能表 第20篇--V$resource_limit 2007.6.15 就一条SQL语句供你参考: select * from V$RESOURCE_LIMIT where resourc ...
- 系列文章--C#即时通讯开发
对使用UDP协议和大规模即时通讯的思考 C#[Fox即时通讯核心] 开发记录之五 (客户端界面基窗体基本完成) C#[Fox即时通讯核心] 开发记录之四(服务端多线程异步处理数据 主程序大致结构 ...