2014-02-28 26 views
1

我有一堆帶有位置字段的文檔,並且對於給定的搜索查詢與給定座標,我想根據它們的位置是否在給定座標的25英里範圍內進行分組。然而,在每個組中,我希望結果不是按位置靠近排序的。有沒有優雅的方式來做到這一點?在elasticsearch中,如何通過位置鄰近來對結果進行分組?

作爲一個例子,假設我有以下文件:

[ 
    { id: "1", price: 13.5, coords: $c1 }, 
    { id: "2", price: 10, coords: $c2 }, 
    { id: "3", price: 15, coords: $c3 }, 
    { id: "4", price: 5, coords: $c4 }, 
    { id: "5", price: 1, coords: $c5 }, 
] 

其中$ C1,$ C2,$ C3是$ C 25英里之內,$ 4,$ C5均超過25英里遠從$ c。靠近$ c的訂單爲$ c3,$ c2,$ c1,$ c5,$ c4。當處理按價格從低到高排序的查詢,我想作爲

[ 
    [ 
    { id: "2", price: 10, coords: $c2 }, 
    { id: "1", price: 13.5, coords: $c1 }, 
    { id: "3", price: 15, coords: $c3 }, 
    ], 
    [ 
    { id: "5", price: 1, coords: $c5 }, 
    { id: "4", price: 5, coords: $c4 }, 
    ] 
] 
+0

,如果你發佈一些例子doc和您曾經試圖做到這一點任何疑問它可能會有所幫助。 – mconlin

+0

已添加@mconlin示例。謝謝! – dementrock

回答

2

以這種方式回到組的結果,你可以使用聚合(或小面的前1.0) - 特別是地理距離聚集。這會給你每組結果數量(< = 25英里,> 25英里)。然後,要檢索每個組中的匹配,請將地理距離篩選器與原始查詢一起使用。

在排序,你應該能夠使用像

{ 
    "sort" : [ 
     { "price" : {"order" : "asc"}} 
    ], 
    "query" : { 
     ... 
    } 
} 

要在一個單一的API調用實現這一點,你可以嘗試多搜索API。這是_msearch端點,並會採取類似以下內容:空頭

GET _msearch 
{} 
{ 
    "sort": [ 
    { 
     "price": { 
     "order": "asc" 
     } 
    } 
    ], 
    "query": { 
    "filtered": { 
     "query": { 
     "match_all": {} 
     }, 
     "filter": { 
     "geo_distance_range" : { 
      "from" : "0mi", 
      "to" : "25mi" 
      "pin.location" : { 
       "lat" : $c_lat, 
       "lon" : $c_long 
      } 
     } 
     } 
    } 
    } 
} 
{} 
{ 
    "sort": [ 
    { 
     "price": { 
     "order": "asc" 
     } 
    } 
    ], 
    "query": { 
    "filtered": { 
     "query": { 
     "match_all": {} 
     }, 
     "filter": { 
     "geo_distance_range" : { 
      "from" : "25mi" 
      "pin.location" : { 
       "lat" : $c_lat, 
       "lon" : $c_long 
      } 
     } 
     } 
    } 
    } 
} 

拿筆記({})每個查詢之前。我用Sense進行測試,並解析了一些問題 - 在發送之前使用Ctrl + I取消JSON縮進。

這將返回一個響應數組,每個查詢一個響應 - 每個響應等效於在Search API中使用相應查詢的結果。

如果您的用例始終顯示所有結果,那麼第二種方法將是適當的並滿足單個API調用的要求。但是,如果要單獨顯示結果組,則第一種方法可能更有效,因爲您不會檢索未使用的結果。

如果此解決方案不能滿足您的需求,請爲問題添加更多細節,我會再次考慮!

鏈接:

+0

我給這個問題增加了一個例子。理想情況下,如果可能的話,我會在一次調用elasticsearch的時候這樣做。否則,我總是可以首先使用<= 25英里的過濾器進行搜索,然後當結果進入最後一頁時,使用> 25英里的過濾器執行另一個查詢,這是一個不太優雅的解決方案。 – dementrock

+2

你可以使用多搜索API(http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-multi-search.html) 這將允許你做兩個搜索一個電話。 – Akshay

+0

謝謝@Akshay - 很好找!我已經測試過並更新了答案。 –

相關問題