solr搜索最近距离的使用教程

说明:

solr4之后支持空间搜索。

它底层使用的时Bkd树,标准的临近搜索算法。

本文是教你怎么使用,其他不多赘述,只说如何做到以下两点:

1.距离45,94经纬度300km内的所有点,按升序排列,可分页。

2.距离45,94最近的点,按升序排列,可分页,并返回距离。

 

你需要先做一番工作:

配置:

我们新建一个名字叫geo的core,打开它的配置文件managed-schema,里面有这样一个叫做location的fieldType

 <fieldType name="location" class="solr.LatLonPointSpatialField" docValues="true"/>

接下来我们新建一个field,引入该fieldType.

<field name="loc" type="location" indexed="true"/>

你需要注意的是以下两点:

1.这个location实际上就是解析经纬度的。只要有field使用type=location,就意味着该field的值是“lat,lon”,即“纬度,经度”,比如“43.333,26.1122”;

2.loc我添加了indexed=true,该作用是将经纬度放到BKD树里,如果不使用indexed而是启用docValues=true时,纬度和经度对被比特交织成64位并放入Lucene DocValues,docValues数据的准确性约为1厘米。我还不能理解什么是比特交织,你也可能不会用到这段话,了解即可。

往里面添加数据:

此时因为geo——core里面有必填的id,以及我们设定的loc.

我用java添加数据的,添加了9999条数据:

添加的格式伪代码如下:

Random r = new Random();//随机数
for(i<<<10000){
    "id" = i+"_solr";
    //纬度范围是-90~90,经度范围-180~180
    "loc" = (r.nextInt(180)-90)+","+(r.nextInt(360)-180));

}

添加后的数据大约长这样:

准备工作做完了,开始搜索:

1.距离45,94经纬度300km内的所有点,按升序排列,可分页。

  q=*:*&fq={!geofilt}&sfield=loc&pt=45,94&d=300&sort=geodist() asc&start=0&rows=5

  红字是可以替换的,蓝字是分页.

此时结果就已经排序了.

例如:

http://localhost:8983/solr/geo/select?q=*:*&fq={!geofilt}&sfield=loc&pt=45,94&d=1000&sort=geodist()%20asc&start=1&rows=5

%20是空格的URL编码

结果:

2.距离45,94最近的点,按升序排列,可分页,并返回距离。

&q={!func}geodist()&sfield=loc&pt=45,94&sort=score+asc&fl=*,score

直接上结果:

可以看到效率很高的.

这两个功能一般都足够使用了.教程至此结束.

 

 

2019.4.18

有同学更复杂的不好写,java代码粘出来,大致如下:

/**
	 * 搜索最近距离的商品,附带条件商品标题关键字和类型 条件
	 * @param keyword 商品标题关键字
	 * @param type 类型
	 * @param pt 坐标点
	 * @param page 分页
	 * @param rows 分页
	 * @return
	 */
	public SolrDocumentList queryDonations(String keyword, Integer type,String pt,  int page, int rows){
		/**
		 * 创建query对象
		 */
		SolrQuery query = new SolrQuery();
		query.setQuery("{!func}geodist()");
		query.setSort("score ", SolrQuery.ORDER.asc);
		query.addField("*,score");
		query.setStart((page - 1) * rows);
		query.setRows(rows);
		Map<String, String> map = new HashMap<>();
		map.put("sfield", "loc");//loc是solr坐标字段
		map.put("pt", pt);//中心坐标条件
		SolrParams arg0 = new MapSolrParams(map);
		query.add(arg0);
		
		/**
		 * keyword条件 和type条件
		 */
		if (!StringUtils.isBlank(keyword)) {
			query.addFilterQuery("title:" + "\"" + keyword + "\"");
		}
		if (type != null) {
			query.addFilterQuery("type:" + type);
		}
		....//执行查询
		....
	}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值