2017-08-11 10 views
0

私はElasticsearchで新しくなっていますので、次の作業で正しく開始する方法がわかりません。Elasticsearchカスタムプラグイン:検索前に追加のクエリパラメータを追加

私はフィールドの2種類が含まれるドキュメントを使用して索引があります。

  • アドレス:都市と通りを含む文字列を、
  • ハウス:ハウスの数字(整数)のリスト。通常の場合には

私がfollowinクエリによって、この文書を検索できます。

(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' 

すなわち(1)に(2)クエリを変換し、それが 'アドレス' から、家屋番号 '33' をカットし、 '家' としてそれを入れて検索が実行される前に同じクエリにmatch-parameterを指定します。

「アドレス」(解析は問題ではない)からハウスナンバーを抽出するプラグインをJavaで作成し、この値を持つ「ハウス」という余分なパラメータを追加することができたと思います。

このように私の問題は、次のとおりです。

  1. 検索が実行する前に、私のプラグインで、私はプログラム的に私のクエリに余分なマッチパラメータの家」を追加することができますか?
  2. 'address'パラメータから後続のhouse-numberトークンを削除する方法はありますか?

答えて

0

チェックアウト次の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()はREST応答に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)

また、私はElasticSearch 2.4.2用のプラグインを開発しで(BaseRestHandler由来)RESTアクション・クラスを追加した最後にwildcards

+0

もちろん#1クエリが必要なレコードを見つけたが、それはすべての住宅を持つすべてのレコードを検索します。私の場合、私は家#33でレコードを見つけるしかありません。さらに複雑なのは、ハウスナンバーは「アドレス」パラメータに文字列全体として含める必要があります。 私は説明します:顧客のフロントエンドはアドレスとして単一文字列のみをサポートしています。また、私は弾性に送信する前に、この文字列を2つのパラメータに分割するためにこの文字列を前処理する機会がありません。だから私はelasticsearchでこの前処理を完全に行うべきです。 –

関連する問題