//solr4.1 java client 地理搜索 查询用法总结
1. notice
d 和 score 都是弧度值,过滤前需要将距离转为弧度,例如 12km,
double dvalue = DistanceUtils.dist2Degrees( 12, DistanceUtils.EARTH_MEAN_RADIUS_KM);
查询获取得分后的值也是弧度值,需要转为距离km值,如下
double distKm = DistanceUtils.degrees2Dist( Double.valueOf (list.get(i).getFieldValue("score").toString() ), DistanceUtils.EARTH_MEAN_RADIUS_KM);
2. notice
<
prefixTree="geohash"
geo="true"
distErrPct="0.025"
distCalculator="vincentySphere" //文森特球面公式,默认是haversine distance
maxDistErr="0.000009"//这个参数与 maxLevels 二者选其一吧,默认是11,
units="degrees" />
参数与精度
测试过程中发现,调整disCalculatior,距离精度值略微有差异,100m的话,可以直接haversion distance
更精确的话,采取vincentySphere,二者在100m外都相同,只在最后m一些有些不同。 maxLevels参数值也会影响性能、计算的小数点尾数值
watcher example
下面的测试d都是弧度值,注意弧度值范围是 [0,180],
//得分是按照setQuery部分计算,filterquery部分对query部分结果做过滤 // query.setQuery( "childCategoryId:100002");
// query.addFilterQuery("{! field f=location} Intersects( Circle(22.48,108.19 d=20))" );
//这种查询语法支持,单由于query部分缺失,结果为0
//query.addFilterQuery("{! field f=location} Intersects( Circle(22.48,108.19 d=20))" );//无结果
//不支持的查询语法 //query.setQuery("childCategoryId:100002 AND {! field f=location } Intersects( Circle(22.48,108.19 d=20))" );//不支持
//支持的查询语法,效果等同 childCategoryId:100002 加上后面的过程,没有按照距离排序,距离值作为常量得分加上文本得分。距离部分不影响查询结果数量,只是影响查询得分 //query.setQuery("childCategoryId:100002 AND {! score=distance} location:"Intersects( Circle(22.48,108.19 d=20))" " );
//按距离排序,关键词部分作为filterquery,注意query 与 filter query的 位置,按距离排序 //query.setQuery("{! score=distance} location:"Intersects( Circle(22.48,108.19 d=20))" " );
//query.addFilterQuery("childCategoryId:100002");
//纯按照距离排序,此时没有文本部分的查询,按距离排序
//query.setQuery("{! score=distance} location:"Intersects( Circle(22.48,108.19 d=20))" " );
//距离仅仅用作排序,但不过滤 query.setQuery("{! score=distance filter=false} location:"Intersects( Circle(22.48,108.19 d=20))" ");
query.addField("*,score");
query.addField("location,id,score");
query.setSortField("score", ORDER.asc);
query.setStart( 0 );
query.setRows( 160 );
//query.set("debugQuery", "on");
query.setParam("echoParams", "explicit");
QueryResponse response = bean.query(query);//bean封装EmbededServer
System.out.println("response.numFound= "+ response.getResults().getNumFound() );
System.out.println("response.maxScore= "+ response.getResults().getMaxScore() );
System.out.println("response.getResult.size= "+ response.getResults().size() );
if( response!= null ){
SolrDocumentList list = response.getResults();
for( int i=0; i< list.size(); i ++)
System.out.println( list.get(i) );
}
其中location 对应
<name="location" type="geohash" indexed="true" stored="true" multiValued="false"/>
spatialContextFactory="com.spatial4j.core.context.jts.JtsSpatialContextFactory"
prefixTree="geohash"
distErrPct="0.025"
maxDistErr="0.000009"
distCalculator="vincentySphere"
units="degrees" />
这个location域数据格式 lat,lon 值对