Elasticsearch 普通模板查询 + 代码块模板查询 + 函数使用 + 代码实现

ES 版本

{
  "name" : "7120422556f7",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "ZoEJVIlxSFiynXyYnr_pAA",
  "version" : {
    "number" : "7.4.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "2f90bbf7b93631e52bafb59b3b049cb44ec25e96",
    "build_date" : "2019-10-28T20:40:44.881551Z",
    "build_snapshot" : false,
    "lucene_version" : "8.2.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

参考

https://www.elastic.co/guide/en/elasticsearch/reference/current/search-template.html
https://blog.csdn.net/qq330983778/article/details/103625290

语法示例

Elasticsearch 是支持 Mustache (胡子)语法的,这使得即使是通过 json 格式交互,也能充满无限的可能了

{{data}} - 传参
{{#data}} {{/data}} - data没有或为 false 此对标签包裹的内容将不显示
{{^data}} {{/data}} - 和上面一个相反
{{.}} - 表示枚举,可以循环输出整个数组
{{<partials}} - 以>开始表示子模块
{{{data}}} - {{data}}输出会将等特殊字符转译,如果想保持内容原样输出可以使用{{{}}}
{{!comments}} - 可用作注释,不会影响最终结果

常用

相当于 if else

{{#condition}}if content{{/condition}} {{^condition}}else content{{/condition}}

普通模板

删除已创建的模板

DELETE _scripts/my_search_template

创建模板

PUT _scripts/my_search_template
{
  "script": {
    "lang": "mustache",
    "source": {
      "from": "{{from}}",
      "size": "{{size}}",
      "query": {
        "term": {
          "productCode": "{{productCode}}"
        }
      }
    },
    "params": {
      "from": null,
      "size": null,
      "productCode": null
    }
  }
}

查看已创建的模板

POST _render/template
{
  "id": "my_search_template",
  "params": {
    "from": 0,
    "size": 10,
    "productCode": "1"
  }
}

根据模板查询

GET my_job_index/_search/template
{
  "id": "my_search_template",
  "params": {
    "from": 0,
    "size": 10,
    "productCode": "1"
  }
}

代码块模板

顾名思义,可以在里面添加一些代码块,比如 if else 之类的简单逻辑,还可以使用很多函数,比如 toJson 可以转换为 json 字符串。

删除模板

DELETE _scripts/my_function_template

创建模板

但由于 json 格式的缘故,{{#productCode}} 这种格式不被认可,需要转义,使用 “”" json “”" 这种结构即可
还需要注意的是,最终生成的语法如果是 query:{} 查询会报异常,es 不允许 query 是空的

PUT _scripts/my_function_template
{
  "script": {
    "lang": "mustache",
    "source": """
    {
      "from": "{{from}}",
      "size": "{{size}}",
      "_source":[
        "systemSource",
        "productCode"
      ],
      "query": {
       "bool": {
         "filter": [
           {
             "term": {
               "systemSource": "sys"
             }
           }
           {{#productCode}}
           ,
           {
             "term": {
               "productCode": {{productCode}}
             }
           }
           {{/productCode}}
         ]
      }
     }
    }
    """,
    "params": {
      "from": null,
      "size": null,
      "productCode": null
    }
  }
}

执行查询,productCode 有值

GET my_job_index/_search/template
{
  "id": "my_function_template",
  "params": {
    "from": 0,
    "size": 10,
	"productCode": "1"
  }
}

当 productCode 没有值 或者为 false 的时候,则 term 代码块不会出现
“productCode”: null 或者 “productCode”: “” 或者 “productCode”: false

GET my_job_index/_search/template
{
  "id": "my_function_template",
  "params": {
    "from": 0,
    "size": 10
  }
}

文件模板

在 es 路径下 config/scripts,创建文件,后缀名必须为.mustache,例如:my_complex_template.mustache 内容跟以上 source 一样,my_complex_template 为 id,不过内容包含代码块不用转义

Java 代码

仅供参考

import cn.hutool.json.JSONUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.script.ScriptType;
import org.elasticsearch.script.mustache.SearchTemplateRequest;
import org.elasticsearch.script.mustache.SearchTemplateResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 功能描述
 *
 * @author jason
 */
@Slf4j
@RestController
@RequestMapping("/template")
public class EsTemplateController {

    @Autowired
    private RestHighLevelClient client;

    /**
     * 模板查询
     * http://127.0.0.1:9090/template/search?keyword=2
     */
    @SneakyThrows
    @GetMapping("/search")
    public Object search(@RequestParam(required = false) String keyword) {
        SearchTemplateRequest request = new SearchTemplateRequest();
        request.setRequest(new SearchRequest("my_job_index"));

        request.setScriptType(ScriptType.STORED);
        request.setScript("my_function_template");

        Map<String, Object> params = new HashMap<>();
        params.put("from", 0);
        params.put("size", 5);
        params.put("productCode", keyword);
        request.setScriptParams(params);

        SearchTemplateResponse response = client.searchTemplate(request, RequestOptions.DEFAULT);
        SearchResponse searchResponse = response.getResponse();

        return Arrays.stream(searchResponse.getHits().getHits())
                .map(item -> JSONUtil.parse(item.getSourceAsString()))
                .collect(Collectors.toList());
    }

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值