1. 程式人生 > >ElasticSearch【5】模板搜索API

ElasticSearch【5】模板搜索API

sage lin 填充 6.5 map 指定 索引 比較 gis

ElasticSearch Rest高級API 提供了多種搜索方式,除了前面講到的search查詢,ElasticSearch 還提供了通過模板搜索查詢。我個人比較喜歡這種方式。

我們可以通過腳本預選註冊模板,在註冊模板時定義一個模板名稱。在查詢時通過模板名稱調用該模板。首先演示下如何註冊模板:

public void registTemplate(){
        RestClient restClient = elasticClient.getRestClient();
        String template = "{\n" +
                            "  \"script\":{\n" +
                            "    \"lang\":\"mustache\",\n" +
                            "    \"source\":{\n" +
                            "      \"query\":{\n" +
                            "        \"match\":{\n" +
                            "          \"{{key}}\":\"{{value}}\"\n" +
                            "        }\n" +
                            "      },\n" +
                            "      \"size\":\"{{size}}\"\n" +
                            "    }\n" +
                            "  }\n" +
                            "}";
        Request scriptRequest1 
= new Request("POST", "_scripts/title_search"); scriptRequest1.setJsonEntity(template); try { restClient.performRequest(scriptRequest1); restClient.close(); } catch (IOException e) { e.printStackTrace(); } }

由於ElasticSearch 6.5版本的高級Rest API中暫時還沒有提供用於註冊模板的存儲腳本,所以本示例中使用的低級REST客戶端。本示例中註冊了一個名為“title_search”的模板

有了這個模板就可以通過“title_search”去調用,動態的將查詢參數添加到模板中去。模板調用示例如下:

public void templateSearch(){
        RestHighLevelClient client = elasticClient.getRestHighLevelClient();
        try {
            SearchTemplateRequest request = new SearchTemplateRequest();
            request.setRequest(new SearchRequest("posts"));

            request.setScriptType(ScriptType.STORED);
            request.setScript(
"title_search"); Map<String, Object> params = new HashMap<>(); params.put("key", "name"); params.put("value", "福賣福"); params.put("size", 5); request.setScriptParams(params); try { SearchTemplateResponse searchTemplateResponse = client.searchTemplate(request, RequestOptions.DEFAULT); SearchHit[] hits = searchTemplateResponse.getResponse().getHits().getHits(); for (SearchHit hit : hits) { System.out.println(hit.getSourceAsString()); } client.close(); } catch (IOException e) { e.printStackTrace(); } } catch (Exception e) { e.printStackTrace(); } }

針對每個模板我們執行一次搜索請求,如果我們工作中針對同一模板可能會有不止一次的請求,如果每個請求都去單獨執行的話未免有點繁瑣。我們可以通過msearchTemplate

來實現一次請求實現多條搜索,示例如下:

public void multiTemplateSearch(){
        RestHighLevelClient client = elasticClient.getRestHighLevelClient();
        String [] searchTerms = {"周大福", "特博士", "詹姆斯"}; // 要搜索的條件
        MultiSearchTemplateRequest multiRequest = new MultiSearchTemplateRequest();
        for (String searchTerm : searchTerms) {
            SearchTemplateRequest request = new SearchTemplateRequest();
            request.setRequest(new SearchRequest("posts")); //指定為posts索引庫

            request.setScriptType(ScriptType.INLINE);
            request.setScript(
                    "{\n" +
                            "  \"query\":{\n" +
                            "    \"match\":{\n" +
                            "      \"{{key}}\":\"{{value}}\"\n" +
                            "    }\n" +
                            "  },\n" +
                            "  \"size\":\"{{size}}\"\n" +
                            "}");

            Map<String, Object> scriptParams = new HashMap<>();
            //向模板中填充對應值
            scriptParams.put("key", "name");
            scriptParams.put("value", searchTerm);
            scriptParams.put("size", 5);
            request.setScriptParams(scriptParams);

            multiRequest.add(request);
        }
        //執行查詢
        try {
            MultiSearchTemplateResponse multiResponse = client.msearchTemplate(multiRequest, RequestOptions.DEFAULT);
            //返回一組響應 ,每個請求對應一個響應
            for (MultiSearchTemplateResponse.Item item : multiResponse.getResponses()) {
                if (item.isFailure()) {
                    String error = item.getFailureMessage(); //搜索請求失敗返回錯誤信息
                }else {
                    SearchTemplateResponse searchTemplateResponse = item.getResponse();
                    SearchResponse response = searchTemplateResponse.getResponse();
                    SearchHits hits = response.getHits();
                    System.out.println("----------");
                    for (SearchHit hit : hits) {
                        System.out.println(hit.getSourceAsString());
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

執行結果如下

技術分享圖片

ElasticSearch【5】模板搜索API