Solr的空间索引
Posted 莫西里
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Solr的空间索引相关的知识,希望对你有一定的参考价值。
一、Solr空间搜索的目的
(1)索引空间点数据和其他形状的数据
(2)通过圆形、正方形或者其他形状进行过滤搜索结果
(3)通过两个点之间的距离或者是两个多边形的形状进行排序或者评分
二、Solr空间搜索的域类型(FieldType)
1 、LatLonType与POINT
这两种类型都是数据点类型。LatLonType类型存储一个点在地图上的经纬度信息。POINT类型则是存储一个点在坐标上的x y位置。点类型数据的表达方式为lat(x),lon(y)。
2、SpatialRecursivePrefixTreeFieldType类型(缩写为RPT类型)
A、RPT除了能够在圆形和正方形外,还能在多边形和其他复杂的形状进行搜索
B、对点和多边形(线、多边形)进行索引创建。
C、多值的距离上的排序和评分boost
RPT域类型使用时,需要在模式文件中进行创建:
(1)下载JTS
JTS的下载地址:http://download.csdn.net/detail/u011518678/9613072
将JTS下载后,直接将jts的jar放入到solr web工程下的lib文件夹即可。
(2)配置RPT域类型,创建多边形域
<fieldType name="shape_rpt" class="solr.SpatialRecursivePrefixTreeFieldType"
spatialContextFactory="com.spatial4j.core.context.jts.JtsSpatialContextFactory" distErrPct="0.025" maxDistErr="0.000009" units="degrees"></fieldType>
<field name="shape" type="shape_rpt" indexed="true" stored="true"></field>
field的定义不在过多描述,下面主要介绍RPT域类型相关的属性:
name:域类型的名称
class:该类型的数据有那个类进行处理,这里使用solr.SpatialRecursivePrefixTreeFieldType
spatialContextFactory:solr本身只支持点和矩形的形状处理,需要通过JTS工具来扩展多边形的功能。如果需要的话则需要扩展JTS jar中的JtsSapatialContextFactory对象。需要注意的是,solr5.x和solr6.x版本中的ContexntFacotory的package路径是不一样的,solr5:com.spatial4j.core.context.jts.JtsSpatialContextFactory,solr6:org.locationtech.spatial4j.context.jts.JtsSpati
,所以用户在配置RPT域类型时要根据自己的solr版本配置不同的包路径。
maxDistErr:定义索引数据的最高界别,默认是地面1米(0.000009度)。
unutis:索引的数据所使用的单位,可以定义为degrees,kilometers和miles,默认值为kilometers
distErrPct:0-0.5之间的范围,定义了距离的经度,当值越消失,则精度越高。
(3)操作多边形数据
创建索引:
在创建索引时,需要注意多边形在索引数据中的表达方式:
点的表达方式为:POINT(0 0)
线的表达方式为:LINESTRING(0 0,1 0,0 0),线段由多个点组成,线段当含有多个点时,则是折线
多边形的表达方式:POLYGON(0 0,1 0,1 1,1 0,0 0 ),多边形的表达方式需要形成闭合图形,但是笔者没有证明POLYGON(0 0,1 0,1 1,1 0,0 0 )是否和POLYGON(0 0,1 1,0 1,1 0,0 0 )是否为同一个图形
关于空间类型的WKT表示方法,详细请看如下地址:https://en.wikipedia.org/wiki/Well-known_text
/**
* @author wozipa
* @throws IOException
* @throws SolrServerException
* @Date 2016-8-24 9:53
* @see 所以多边形文件
* POLYGON((0 0,0 1,1 1,1 0,0 0))
* POIN(0 0)
* LINESTRING(0 0,1 0,0 0)
*/
public void indexPolygon() throws SolrServerException, IOException
HttpSolrClient client=new HttpSolrClient("http://192.98.12.36:8983/solr/Test");
SolrInputDocument document=new SolrInputDocument();
document.addField("id", "test4");
document.addField("shape", "POIN(0 0)"); //空间点表示方法:POIN(0 0)
document.addField("shape", "LINESTRING(0 0,1 0,0 0)"); //空间线表示方法:LINESTRING(0 0,1 0,0 0),三个点,形成闭合图形
document.addField("shape", "POLYGON((0 0,0 1,1 1,1 0,0 0))"); //空间多边形表示方法:POLYGON((0 0,0 1,1 1,1 0,0 0)),这里表示一个四边形
//五个点,形成闭合图形
client.add(document);
client.commit();
索引的结果为:
"id": "test4",
"shape": "LINESTRING(0 0,1 0,0 0)",
"_version_": 1543642553156370400
创建查询:
多边形的查询则为两个多边形的关系,主要包括:相交(Intersects),包含(Contains),被包含(Within),相等(Equals)和相拒(Disjoint),查询的基本公式为:
"action+polygon":例如
"Intersects(POLYGON(0 0,1 0,1 1,0 1,0 0))"
空间索引数据查询的代码为:
/**
* @author wozipa
* @Date 2016-8-24 10:12
* @see 对该多边形就行查询
*/
public void queryPolygon()
HttpSolrClient client=new HttpSolrClient("http://192.98.12.36:8983/solr/Test");
SolrQuery query=new SolrQuery();
query.setQuery("shape:\\"Intersects(POLYGON((0 0,0 0.5,0.5 0.5,0.5 0,0 0)))\\"");
try
SolrResponse response=client.query(query);
System.out.println(response.toString());
catch (SolrServerException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
/**
* @author wozipa
* @Date 2016-8-24 11:08
* @see 查询点
*/
public void queryPoint()
HttpSolrClient client=new HttpSolrClient("http://192.98.12.36:8983/solr/Test");
SolrQuery query=new SolrQuery();
query.setQuery("shape:\\"Intersects(POINT(2.1 2.1))\\"");
try
SolrResponse response=client.query(query);
System.out.println(response.toString());
catch (SolrServerException e)
// TODO Auto-generated catch block
e.printStackTrace();
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
3、BBoxField
该类型是solr6版本中新增加的,是一个RPT类型的一个变种(我认为是简化版本),对举行表示式发生了改变:ENVELOPE(minX,maxX,maxY,minY)
ENVELOPE(-10, 20, 15, 10)
该类型的使用方式基本和POLYGON是相同的,主要为数据的定义:
<field name="bbox" type="bbox" />
<fieldType name="bbox" class="solr.BBoxField"
geo="true" units="kilometers" numberType="_bbox_coord" storeSubFields="false"/>
<fieldType name="_bbox_coord" class="solr.TrieDoubleField" precisionStep="8" docValues="true" stored="false"/>
笔者没有对该类型进行研究,就是简单的提示一下solr用户,在solr6中新增加了一种矩形的表达方式。
三、过滤器
在空间搜索中,solr还提供了两种常用的filter,用来对结果集进行过滤筛选,过滤器拥有共同的参数类型,下面先介绍一下各个参数类型
1、参数
(1)d
两个多边形之间的线性距离,默认使用单位为千米(1km=0.009度),可以d进行单位定义
(2)pt
中心点位置,使用x,y进行点的表示。
(3)sfield
进行空间过滤的域名城,即该名称的空间数据将被用于数据过滤
(4)filter
过滤器名城,主要有两种类型,geofilter和bbox
通过这四个参数可以确定一个范围,该范围外的数据将被过滤掉。
2、过滤器类型
(1)geofilt
该类型将生成一个以pt为中点,以d为半径,形成一个圆形,该圆形中的数据符合过滤器的条件,不会被过滤掉。
使用例子为:fq=!geofilt sfield=store&pt=45.15,-93.85&d=5,可以将所有的条件数据写入到大括号内:
fq=!geofilt sfield=store
pt=45
15,-93.85 d=5
(2)bbox
该过滤器,会先画一个域geofilt相同的圆,然后形成一个与圆外切的正方形,该正方形中的数据通过过滤器,起范围表示为下图中的蓝色方框:
使用方式为:fq=!bbox sfield=store&pt=45.15,-93.85&d=5,其用法如上:
四、总结
该问主要讲解了solr对多边形(点、线、多边形)数据的索引与搜索,同时还提供了空间搜索中相关的过滤器,希望大家共同学习,如果有什么不正确的地方,还望大家指出。
以上是关于Solr的空间索引的主要内容,如果未能解决你的问题,请参考以下文章