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 ...
随机推荐
- JDBC方式操作数据库
1.读取配置文件,我将配置信息写入配置文件(.properties)中,方便后期数据库变更后或者其他项目使用,扩展性好些,尽量避免硬编码. driver=oracle.jdbc.driver.Orac ...
- 【Swoole】简单安装与创建TCP服务器
pecl install swoole PHP的异步.并行.高性能网络通信引擎,使用纯C语言编写,提供了php语言的异步多线程服务器,异步TCP/UDP网络客户端,异步MySQL,异步Redis,数据 ...
- 维度属性的KeyColumns,NameColumn和ValueColumn
维度的每一个属性都有KeyColumns,NameColumn和ValueColumn 1,如何理解KeyColumns,NameColumn和ValueColumn?对一行记录有不同的标识列,但 ...
- 【疯了Labview】(一)仿JKI的RCF 挂件
最近在疯狂的学习C#中,学习的最好的一个途径便是论坛,发帖,看帖和被骂,新手往往在这个过程中慢慢长大一直想做个类似JKI RCF挂件的东西,目前实现了,想想其实思路也不是很难, RCF是JKI做的通过 ...
- SQL SERVER 集合
死锁和堵塞一直是性能测试执行中关注的重点. 下面是我整理的监控sql server数据库,在性能测试过程中是否出现死锁.堵塞的SQL语句,还算比较准备,留下来备用. --每秒死锁数量 SELECT * ...
- 分享知识-快乐自己:Spring线程池配置
Spring通过ThreadPoolTaskExecutor实现线程池技术,它是使用jdk中的Java.util.concurrent.ThreadPoolExecutor进行实现. Spring 配 ...
- Python—numpy.flatnonzero()
numpy.flatnonzero(): 该函数输入一个矩阵,返回扁平化后矩阵中非零元素的位置(index) 这是官方文档给出的用法,非常正规,输入一个矩阵,返回了其中非零元素的位置. 1 >& ...
- [项目部署] CentOs7 安装 MySQL/Tomcat/JDK 笔记
0.安装 MySQL cd /usr/local/ # 新增yum源 rpm -Uvh http://dev.mysql.com/get/mysql-community-release-el7-.no ...
- Android开发中java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx}
Android开发中java.lang.RuntimeException: Unable to start activity ComponentInfo{xxx}: java.lang.NullPoi ...
- LeetCode Reverse Words in a String III
原题链接在这里:https://leetcode.com/problems/reverse-words-in-a-string-iii/#/description 题目: Given a string ...