elasticsearch script实战

写在前面

大家在开发elasticsearch的时候都会遇到很多去怪的需求,如果我们已知的RestAPI无法帮助我们完成搜索,是就需要我们自己动手写脚本来辅助搜索,完成需求.

浅谈elasticsearch-script脚本使用机制

通过阅读官方文档我们可以了解到es所使用的脚本语言是painless这是一门安全-高效的脚本语言,基于jvm的,总而言之对于java语言的小伙伴来说是非常友好的.

其实es本身还支持一些脚本语言,如早期的Groovy甚至是更早的MVEL,当然es肯定也是支持java的毕竟自身就是用java写的.

script的多种状态

在es中脚本的使用分为几个阶段,这个阶段和脚本的运行环境有着直接的关系

这张表是官网提供的一个使用关系对照表,记录了我们所使用的脚本和es中使用脚本的位置.

脚本的正确使用方式

es中脚本的运行必然伴随着大量的计算,因为问的的数量随便就是几个G对于脚本的安全使用es自身做了一些限制.

每分钟创建的脚本数量

在使用脚本是,不应该直接把参数写在脚本中,而是通过param将变量通过传参的形式传入到脚本中,这样我们即使有大量的查询,使用的依然是同一个脚本

谨慎的编写脚本

由于es中文档的数量非常庞大,在使用脚本进行辅助查询的时候肯能会出现脚本编写方式不对导致响应时间过长,这种情况我们可以使用kibana中提供的分析工具来观察我们的查询语法.

这个图是简单的写了一个bool查询,再配合一个filter的script查询

实战记录

先描述下自己遇到的需求:es中存有一个题库,题库中可能会存在两道或者是多道相似的试题,需要我将相似的试题查出来

这里只是简单地介绍下使用脚本的过程具体详情可以看我的另一篇文章

我的做法

需求看似比较简单的一句话,实际上还是有很多坑的.下面我先吧我的做发放出来

  1. 创建一个新的索引使用别名将线上的业务切换过去
  2. 停止数据写入,只提供查询服务
  3. 全量获取一遍数据的id
  4. 取出一个id获取对应数据放入es中进行搜索
  5. 搜索结果大于1记录这两个id
{
  "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对搜索结果进行过滤,实际产出的效果还算理想吧,但是对于短文章还是会有些问题,这个是我个人搜索语法编写的还是不到位

写在后面

把使用到的相关资料放在下面:

  • painless教程
  • elasticsearch-script教程

你可能感兴趣的:(ELK,Elasticsearch)