2014-01-15 27 views
2

似乎找不到我的疑問的答案,所以我決定發佈問題,看看有人能幫助我。從elasticsearch檢索信息,按輸入數組的順序

在我的應用程序中,我有一個來自後端的ID數組,它已經按我的要求排序,例如: [0] => 23,[1] => 12,[2] = > 45,[3] => 21

然後,我使用條件過濾器「詢問」elasticsearch對應於此數組中每個id的信息。問題是結果不是按照我發送的ID的順序出現的,所以結果會混淆,如:[0] => 21,[1] => 45,[2] => 23,[3 ] => 12

請注意,我無法通過對後端數組進行排序的排序對elasticsearch進行排序。

我也不能在PHP中命令它們,因爲我正在從elasticsearch中檢索分頁結果,所以如果每個oage都有2個結果,那麼elasticsearch只能給我提供[0] => 21,[1] = > 45,所以我甚至不能用php命令它們。

如何獲得輸入數組排序的結果?有任何想法嗎?

在此先感謝

+0

我不認爲這是可能的彈性做,這意味着你需要做到這一點,一旦你得到的結果回 –

回答

2

這裏是你能做到這一點,使用自定義腳本的得分方式之一。

首先,我創建了一些假的數據:

curl -XPUT "http://localhost:9200/test_index" 

curl -XPOST "http://localhost:9200/test_index/_bulk " -d' 
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 1 } } 
{ "name" : "Document 1", "id" : 1 } 
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 2 } } 
{ "name" : "Document 2", "id" : 2 } 
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 3 } } 
{ "name" : "Document 3", "id" : 3 } 
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 4 } } 
{ "name" : "Document 4", "id" : 4 } 
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 5 } } 
{ "name" : "Document 5", "id" : 5 } 
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 6 } } 
{ "name" : "Document 6", "id" : 6 } 
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 7 } } 
{ "name" : "Document 7", "id" : 7 } 
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 8 } } 
{ "name" : "Document 8", "id" : 8 } 
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 9 } } 
{ "name" : "Document 9", "id" : 9 } 
{ "index" : { "_index" : "test_index", "_type" : "docs", "_id" : 10 } } 
{ "name" : "Document 10", "id" : 10 } 
' 

我用,即使它是多餘的,因爲"_id"場被轉換爲字符串,並且腳本是整數容易的"id"場。

您可以通過ID與ids過濾器取回一組特定的文檔中:

curl -XPOST "http://localhost:9200/test_index/_search" -d' 
{ 
    "filter": { 
     "ids": { 
     "type": "docs", 
     "values": [ 1, 8, 2, 5 ] 
     } 
    } 
}' 

但這些不一定會按你想要的順序。使用script based scoring,您可以根據文檔ID定義自己的排序。

在這裏我傳入一個參數,該參數是與ID相關的對象列表。評分腳本只是遍歷它們,直到找到當前文檔ID並返回該文檔的預定分數(或者如果未列出,則返回0)。

curl -XPOST "http://localhost:9200/test_index/_search" -d' 
{ 
    "filter": { 
     "ids": { 
     "type": "docs", 
     "values": [ 1, 8, 2, 5 ] 
     } 
    }, 
    "sort" : { 
     "_script" : { 
      "script" : "for(i:scoring) { if(doc[\"id\"].value == i.id) return i.score; } return 0;", 
      "type" : "number", 
      "params" : { 
       "scoring" : [ 
        { "id": 1, "score": 1 }, 
        { "id": 8, "score": 2 }, 
        { "id": 2, "score": 3 }, 
        { "id": 5, "score": 4 } 
       ] 
      }, 
      "order" : "asc" 
     } 
    } 
}' 

和文件以正確的順序返回:

{ 
    "took": 11, 
    "timed_out": false, 
    "_shards": { 
     "total": 2, 
     "successful": 2, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 4, 
     "max_score": null, 
     "hits": [ 
     { 
      "_index": "test_index", 
      "_type": "docs", 
      "_id": "1", 
      "_score": null, 
      "_source": { 
       "name": "Document 1", 
       "id": 1 
      }, 
      "sort": [ 
       1 
      ] 
     }, 
     { 
      "_index": "test_index", 
      "_type": "docs", 
      "_id": "8", 
      "_score": null, 
      "_source": { 
       "name": "Document 8", 
       "id": 8 
      }, 
      "sort": [ 
       2 
      ] 
     }, 
     { 
      "_index": "test_index", 
      "_type": "docs", 
      "_id": "2", 
      "_score": null, 
      "_source": { 
       "name": "Document 2", 
       "id": 2 
      }, 
      "sort": [ 
       3 
      ] 
     }, 
     { 
      "_index": "test_index", 
      "_type": "docs", 
      "_id": "5", 
      "_score": null, 
      "_source": { 
       "name": "Document 5", 
       "id": 5 
      }, 
      "sort": [ 
       4 
      ] 
     } 
     ] 
    } 
} 

這裏是一個可運行的例子:http://sense.qbox.io/gist/01b28e5c038c785f0844abb7c01a71d69a32a2f4

+1

非常感謝你@Sloan Ahrens。我現在測試它,並得到它的工作,謝謝,工作得很好。如果可以的話,我會投票! :) – Alves

+0

投票,因爲您的自定義腳本過濾器的作品。如果elasticsearch在某天原本支持通過給定的id數組進行排序,那將非常好。我認爲在很多情況下,如果您需要根據未搜索到的文檔中存儲的信息進行排序,並且在您僅請求一大塊文檔(例如用於分頁)時對已取回的代碼中的文檔集合進行排序也不太明智, 。 – maddin2code