ElasticSearch模板搜索API

Posted 覆水难收

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ElasticSearch模板搜索API相关的知识,希望对你有一定的参考价值。

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模板搜索API的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch如何在Elasticsearch中使用排名评估API

Elasticsearch java api 基本搜索部分详解

Elasticsearch java api 基本搜索部分详解

ES问题

ES问题

ElasticSearch学习问题记录——Invalid shift value in prefixCoded bytes (is encoded value really an INT?)(代码片段