2013-10-21 38 views
1

使用Solr 4.5和用例是我需要按距離給定路由排序結果。 使用包含1個地理座標的文檔作爲rpt字段geo(感興趣的地點)。我的目標是:http://i.imgur.com/lGgMEal.jpg。我想計算從文檔到給定路線的最短距離,並將其用作提升組件。Solr 4.5:到路由的距離:排序或篩選

當前的嘗試是使用{!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個文件,並且它們具有以下順序:

    • (1)59.7333,7.61283
    • (2)59.6236,10.7263
    • (3)59.6238,10.7385
    • (4) 64.12379,22.14029

    當順序應而得到:

    • (3)59.62 38,10.7385
    • (2)59.6236,10.7263
    • (1)59.7333,7.61283
    • (4)64.12379,22.14029

你可以看看有增強的完整結果calc debug here: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,但我寧願避免開發自定義組件,除非有必要。

我的問題是:

  • 是否有可能在Solr的4。5距離LineString,而不是形狀的中心?
  • 我們可以發送緩衝線作爲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
  1. 這是不可能的(不帶定製Solr的),以獲得的距離從每個文檔的索引點查詢LineString。您將需要編寫一個引用lineString的ValueSourceParser(您可以使用JTS WKT解析器進行分析),並且該引用也引用索引點字段。爲了以文檔爲基礎有效地從文檔中檢索點,請使用LatLonType而不是RPT。 JTS可以計算點與LineString之間的距離,但請記住JTS在歐幾里德空間中運行。爲了獲得更好的準確性,您需要將數據(索引點和lineString)「投影」到以lineString爲中心的投影。 Proj4j可以提供幫助。

  2. RE bufferedLineStrings,您可能有興趣知道Spatial4j的主分支有一個「BufferedLineString」形狀 - 它是Spatial4j的原生形狀。但是,它尚未集成到形狀解析中,因此尚未完全準備好。爲了清楚起見,它已經過很好的測試,我私自使用了一個非開源的解析器。這也是歐洲空間有限的,如JTS。解決這個問題的最好方法是添加你自己的Solr查詢解析器(比聽起來容易)。這個查詢解析器將讀取一個緩衝距離,一個LineString,並使用JTS來緩衝它。投影到形狀的中心點是不可行的,因爲它必須與索引數據對齊,所以您可以通過適當量的過度緩衝進行補償,從而增加形狀大小,但至少要確保捕獲最小距離。我有計劃解決這個問題,但我一直很忙。

+0

謝謝你快速和準確的迴應大衛!這確實回答了我的兩個問題。 我會研究編寫一個新的查詢解析器或可能搜索組件。 –