使用Solr 4.5和用例是我需要按照到给定路线的距离对结果进行排序。
使用包含1个地理坐标的文档作为rpt字段geo
(感兴趣点的位置)。
以下是我的目标:http://i.imgur.com/lGgMEal.jpg。我想计算从文档到给定路线的最短距离,并将其用作增强组件。
目前的尝试是在{!score=recipDistance}
模式下使用edismax
函数,并在WKT中将路由描述作为LineString发送。这是现在发送的查询:
fl=*,score,distdeg:query({!score=distance filter=false v=$spatialfilter})
defType=edismax
q.alt=*:*
boost=query({!score=distance filter=false v=$spatialfilter})
spatialfilter=geo:"Intersects(LINESTRING (59.79619 11.38690, 60.25974 11.63869))"
以URI形式:
http://sokemotortest:8080/solr/collection1/select?fl=*%2Cscore%2Cdistdeg%3Aquery%28{!score%3Ddistance+filter%3Dfalse+v%3D%24spatialfilter}%29&wt=json&debugQuery=true&defType=edismax&q.alt=*%3A*&boost=query%28{!score=distance%20filter=false%20v=$spatialfilter}%29&spatialfilter=geo:%22Intersects%28LINESTRING%20%2859.79619%2011.38690,%2060.25974%2011.63869%29%29%22
我对这种方法的问题是:
Pt(x=60.027965,y=11.512795)
距离计算的结果似乎不对。索引中有4个文档,它们按以下顺序排列:
当订单应该是:
您可以在此处查看boost calc debug的完整结果:pastebin.com/5tvCb0Cf
另一个有效的解决方案可能是按路径距离过滤文档(例如:http://i.imgur.com/EJu8Kcg.jpg)。这可以通过使用似乎在jTS和spatial4j中都支持的缓冲线来完成。唯一的问题是如何将缓冲行作为输入发送到Intersect
函数(如下所示:geo:"Intersects(LINESTRING (59.79619 11.38690, 60.25974 11.63869) d=1)"
)。
这里的解决方案是创建一个自定义搜索组件,它将接受路由作为LineString,并将进一步转发,如Polygon或MuliPolygon,但我宁愿避免开发自定义组件,除非有必要。
我的问题是:
Intersect
函数的输入(像这样:geo:"Intersects(LINESTRING (59.79619 11.38690, 60.25974 11.63869) d=1)"
)?PS:索引中字段的描述:
<field name="geo" type="location_rpt" indexed="true" stored="true"/>
字段类型定义:
<fieldType name="location_rpt"
class="solr.SpatialRecursivePrefixTreeFieldType"
spatialContextFactory="com.spatial4j.core.context.jts.JtsSpatialContextFactory"
geo="true"
distErrPct="0.025"
maxDistErr="0.000009"
units="degrees"
/>
答案 0 :(得分:0)
无法(没有自定义Solr)从每个文档的索引点获取到查询LineString的距离。您将需要编写一个引用lineString的ValueSourceParser(您可以使用JTS WKT解析器进行解析)并且还引用您的索引点字段。为了在每个文档的基础上有效地从文档中检索点,请使用LatLonType,而不是RPT。 JTS可以计算点和LineString之间的距离,但请记住JTS在欧几里德空间中运行。为了获得更好的准确性,您需要将数据(索引点和lineString)“投影”到以lineString为中心的投影。 Proj4j可以提供帮助。
RE bufferedLineStrings,您可能有兴趣知道Spatial4j的主分支具有“BufferedLineString”形状 - 它是Spatial4j的原生。但是,它还没有被整合到形状解析中,所以还没有完全准备好。为了清楚起见,它经过了很好的测试,并且我私下使用了非开源的解析器。这也是欧几里得空间有限,就像JTS一样。解决此问题的最佳方法是添加自己的Solr查询解析器(比听起来更容易)。此查询解析器将读取缓冲区距离,LineString,并从那里使用JTS来缓冲它。投影到形状的中心点是不可行的,因为它必须与索引数据对齐,因此您可以通过适当的量进行过度缓冲补偿,从而增加形状大小但至少确保捕获最小距离。我有计划更好地解决这个问题,但我一直很忙。