2017-08-11 88 views
0

我是Elasticsearch的新手,所以不知道如何正確啓動以下任務。Elasticsearch自定義插件:在搜索之前添加額外的查詢參數

我有一個文件包含2種字段類型的索引:

  • 地址:包括城市和街道的字符串;
  • 房屋:房屋清單(整數)。

在通常情況下,我可以搜索通過跟隨着查詢該文件:

(1)

GET /_search 
{ 
    "query":{ 
    "bool":{ 
     "should": [ 
     {"match": {"address": "Gotham Fourteenth street"}}, 
     {"match": {"houses": 33}} 
     ] 
    } 
    } 
} 

我的目標是通過單一的字符串匹配這樣的記錄,如:

(2)

GET /_search 
{ 
    "query":{ 
    "bool":{ 
     "should": [ 
     {"match": {"address": "Gotham Fourteenth street 33"}} 
     ] 
    } 
    } 
} 

甚至:

curl -X GET 'http://localhost:9200/_search?q=Gotham+Fourteenth+street+33' 

即轉換查詢(2)(1),即從 '地址' 削減房屋號碼 '33',並把它作爲 '房屋'在執行搜索之前將相同的查詢匹配參數。

我想我可以在Java中創建一個插件,從'地址'(解析不是問題)中提取房屋號碼,併爲該值添加一個額外的參數'房屋'。

因此,我的問題是:

  1. 如何在我的插件,我可以通過編程執行搜索前添加一個額外的匹配參數「房屋」我的查詢?
  2. 如何從'地址'參數中刪除尾隨房門號碼?

回答

0

在端我已經開發用於ElasticSearch 2.4.2插件並加入一個REST動作類(來自BaseRestHandler衍生)與以下handleRequest()方法:

@Override 
protected void handleRequest(RestRequest request, RestChannel channel, final Client client) throws Exception { 
    // Get the address parameter 
    String address = request.param("address"); 

    // ... Code that parses address and extracts house number ... 
    int house = ... 

    // Now send both parameters as query to search engine 
    SearchResponse sr = client 
     .prepareSearch("myindex") 
     .setTypes("mytype") 
     // Query all shards, DFS==calculate global words' frequencies 
     .setSearchType(SearchType.DFS_QUERY_THEN_FETCH) 
     // Address string without (cutted) house number 
     .setQuery(QueryBuilders.matchQuery("address", address)) 
     // And extracted house number as second filtering parameter 
     .setPostFilter(QueryBuilders.termQuery("houses", house)) 
     // Starting position of the first returning hit 
     .setFrom(0) 
     // Max number of hits 
     .setSize(10) 
     // Explain hit score 
     .setExplain(true) 
     .get(); 

     // Convert the search response to rest response and send it 
     BytesRestResponse sr_rest = search2restResponse(sr); 
     channel.sendResponse(sr_rest); 
    } 
} 

上述方法search2restResponse()轉換SearchResponse休息響應,看起來如下:

private BytesRestResponse search2restResponse(SearchResponse sr) { 
    SearchHit[] searchHits = sr.getHits().getHits(); 
    StringBuilder builder = new StringBuilder(); 
    builder.append("["); 
    for (int i = 0; i < searchHits.length; i++) { 
     if (i > 0) { 
      builder.append(","); 
     } 
     builder.append(searchHits[i].getSourceAsString()); 
    } 
    builder.append("]"); 
    String res_json = builder.toString(); 
    return new BytesRestResponse(RestStatus.OK, res_json); 
} 
1

curl -X GET 'http://localhost:9200/_search?q=address:"Gotham Fourteenth street"

curl -X GET 'http://localhost:9200/_search?q=address:"Gotham Fourteenth street" AND (houses=13)

而且檢出wildcards

+0

課程的#1查詢查找所需的記錄,但它會找到所有與所有房屋的記錄。在我的情況下,我應該只找到與#33房子的記錄。更復雜的是:門牌號碼應該作爲整個字符串在「地址」參數中。 我會解釋一下:客戶的前端只支持單個字符串作爲地址。另一方面,我沒有機會預處理這個字符串,在發送到彈性文件之前將它分成2個參數。所以我應該在elasticsearch中完成這個預處理。 –

相關問題