Elasticsearch自定义插件:在搜索

时间:2017-08-11 14:42:05

标签: java elasticsearch elasticsearch-plugin

我是Elasticsearch的新手,所以不知道如何正确使用以下任务。

我的索引包含两种类型的字段:

  • 地址:包含城市和街道的字符串;
  • 房屋:房屋清单'数字(整数)。

通常情况下,我可以通过以下查询搜索此文档:

(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中创建一个插件,用于从“地址”中提取门牌号码。 (解析不是问题)并添加一个额外的参数' houses'有这个值。

因此我的问题是:

  1. 如何在我的插件中以编程方式添加额外的匹配参数' house'在搜索执行之前我的查询?
  2. 如何从'地址'中删除尾随门牌号码?参数β

2 个答案:

答案 0 :(得分: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

答案 1 :(得分:0)

最后,我为ElasticSearch 2.4.2开发了一个插件,并使用以下BaseRestHandler方法添加了一个REST动作类(派生自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转换为REST响应,如下所示:

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);
}