大家在开发elasticsearch的时候都会遇到很多去怪的需求,如果我们已知的RestAPI无法帮助我们完成搜索,是就需要我们自己动手写脚本来辅助搜索,完成需求.
通过阅读官方文档我们可以了解到es所使用的脚本语言是painless这是一门安全-高效的脚本语言,基于jvm的,总而言之对于java语言的小伙伴来说是非常友好的.
其实es本身还支持一些脚本语言,如早期的Groovy甚至是更早的MVEL,当然es肯定也是支持java的毕竟自身就是用java写的.
在es中脚本的使用分为几个阶段,这个阶段和脚本的运行环境有着直接的关系
这张表是官网提供的一个使用关系对照表,记录了我们所使用的脚本和es中使用脚本的位置.
es中脚本的运行必然伴随着大量的计算,因为问的的数量随便就是几个G对于脚本的安全使用es自身做了一些限制.
在使用脚本是,不应该直接把参数写在脚本中,而是通过param将变量通过传参的形式传入到脚本中,这样我们即使有大量的查询,使用的依然是同一个脚本
由于es中文档的数量非常庞大,在使用脚本进行辅助查询的时候肯能会出现脚本编写方式不对导致响应时间过长,这种情况我们可以使用kibana中提供的分析工具来观察我们的查询语法.
这个图是简单的写了一个bool查询,再配合一个filter的script查询
先描述下自己遇到的需求:es中存有一个题库,题库中可能会存在两道或者是多道相似的试题,需要我将相似的试题查出来
这里只是简单地介绍下使用脚本的过程具体详情可以看我的另一篇文章
需求看似比较简单的一句话,实际上还是有很多坑的.下面我先吧我的做发放出来
{
"from": 0,
"size": 20,
"query": {
"bool": {
"must": [
{
"bool": {
"must": [
{
"match": {
"stem": {
"query": "情感激励法是通过良好的情感关系",
"operator": "OR",
"prefix_length": 0,
"max_expansions": 50,
"minimum_should_match": "75%",
"fuzzy_transpositions": true,
"lenient": false,
"zero_terms_query": "NONE",
"auto_generate_synonyms_phrase_query": true,
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
}
],
"filter": [
{
"script": {
"script": {
"source": "doc['stem.keyword'].value.length(),
"lang": "painless",
"params": {
"choicesLength": 0,
"stemLength": 460.25
}
},
"boost": 1
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
},
"min_score": 10.5
}
其中使用了文字的长度去做了一个filter对搜索结果进行过滤,实际产出的效果还算理想吧,但是对于短文章还是会有些问题,这个是我个人搜索语法编写的还是不到位
把使用到的相关资料放在下面: