Elasticsearch学习--script

一、概念

 es1.4-5.0,默认脚本语言是Grovvy

es5.0+,默认脚本语言是painless

 二、简单使用

将price减一

# 将id=1的price减一
POST goods/_update/1
{
  "script": {
    "source": "ctx._source.price -= 1"
  }
}

# 简写
POST goods/_update/1
{
  "script": "ctx._source.price -= 1"
}

其中,ctx是一个上下文对象 ,用在对数据的修改上

三、CRUD

1、数据备份

(数据来源可以查看:CSDN

#将goods中的数据备份到goods2中
POST _reindex
{
  "source": {
    "index": "goods"
  },
  "dest": {
    "index": "goods2"
  }
}

2. 新增数组中的值

# 将id=1的tags新增一个值
POST goods/_update/1
{
  "script": "ctx._source.tags.add('无线充电')"
}

3. 根据id删除

# 删除id=11的数据
POST goods/_update/11
{
  "script": "ctx.op='delete'"
}

 4. upsert

如果数据存在执行script中的updated,如果数据不存在,执行upsert中created

POST goods/_update/15
{
  "script": {
    "source": "ctx._source.price += 100"
  },
  "upsert": {
    "name":"香蕉",
    "price": 599
  }
}

第一次执行结果

 第二次执行结果

 5. 查询

使用expression和painless两种语言进行查询,查询结果相同

GET goods/_search
{
  "script_fields": {
    "new_price": {
      "script": {
        "lang": "expression",
        "source": "doc['price'].value * 0.9"
      }
    }
  }
}

GET goods/_search
{
  "script_fields": {
    "new_price": {
      "script": {
        "lang": "painless",
        "source": "doc['price'] * 0.9"
      }
    }
  }
}

painless,doc['age'].value和doc['age']都能正确输出,但是doc['age'] * 0.9报错
expression,doc['age'].value和doc['age']都能正确输出,doc['age'] * 0.9和doc['age'].value * 0.9也都不报错

但是,painless,如果字段为空,*0.9会报错

expression:只能访问数字、布尔值、日期等,存储的字段不可用

es源数据是map类型的,在取值的时候,要根据doc['x xx']取值

update用ctx,查询的时候用doc

6. 参数化查询

给interest加一个值aaa

POST indexname/_update/2
{
  "script": {
    "lang": "painless",
    "source": "ctx._source.interest.add('aaa')"
  }
}

es在首次执行脚本的时候,会对执行的脚本进行编译,并且把编译的结果放在缓冲区内。es的缓冲区默认只有100M,编译操作很消耗性能,es每分钟支持的编译次数是15次
解决方案是:

POST indexname/_update/2
{
  "script": {
    "lang": "painless",
    "source": "ctx._source.interest.add(params.inserest_name)",
    "params": {
      "inserest_name":"bbb"
    }
  }
}

这样,参数是动态传递的,没有硬编码,下次参数内容发生改变,但是脚本没有发生改变,不需要重新编译,节省性能

同理,也可以这样                                                                                                      

GET indexname/_search
{
  "script_fields": {
    "new_age": {
      "script": {
        "lang": "painless",
        "source":"doc['age'].value * params.num",
        "params": {
          "num": 0.9
        }
      }
    }
  }
}

如果是expression,就要把params.num改成num

GET indexname/_search
{
  "script_fields": {
    "new_age": {
      "script": {
        "lang": "expression",
        "source":"doc['age'].value * num",
        "params": {
          "num": 0.9
        }
      }
    }
  }
}

结果数组

GET indexname/_search
{
  "script_fields": {
    "age": {
      "script": {
        "lang": "painless",
        "source":"doc['age'].value"
      }
    },
    "new_age": {
      "script": {
        "lang": "painless",
        "source":"[doc['age'].value - params.num_1,doc['age'].value - params.num_2,doc['age'].value - params.num_3]",
        "params": {
          "num_1": 1,
          "num_2": 2,
          "num_3": 3
        }
      }
    }
  }
}

四、stored scripts:scripts模板

1. 操作脚本

因为脚本编译比较消耗性能,可以把脚本保存在集群的缓存中

语法

/_scripts/{script_id}

创建脚本

POST _scripts/age_num
{
  "script":{
     "lang": "painless",
     "source":"doc['age'].value - params.num"
  }
}

查看脚本

GET _scripts/age_num

使用脚本

GET indexname/_search
{
  "script_fields": {
    "age": {
      "script": {
        "lang": "painless",
        "source":"doc['age'].value"
      }
    },
    "new_age": {
      "script": {
        "id": "age_num",
        "params": {
          "num": 0.9
        }
      }
    }
  }
}

2. scripting的函数式编程

在source中加""",三个双引号

POST indexname/_update/2
{
  "script": {
    "lang": "painless",
    "source": """
       ctx._source.interest.add(params.inserest_name);
       ctx._source.age-=1;
    """,
    "params": {
      "inserest_name": "bbb"
    }
  }
}

如果name中包含aa:name+bb;否则,不操作。==~是匹配的意思

POST indexname/_update/2
{
  "script": {
    "lang": "painless",
    "source": """
      if(ctx._source.name ==~ /[\s\S]*aa[\s\S]*/){
        ctx._source.name+="bb"
      }else{
        ctx.op="noop"
      }
    """
  }
}

for循环取insterst的总数

GET indexname/_search
{
  "aggs": {
    "agg_insterst": {
      "sum": {
        "script": {
          "lang": "painless",
          "source": """
            int total=0;
            for(int i=0; i<doc['interest.keyword'].length;i++){
              total++;
            }
            return total;
          """
        }
      }
    }
  }
}

doc['filed']:会被加载到内存中,效率更高,更消耗内存,只允许简单类型,object和nested属于复杂类型。推荐
params['_source']['field']:每次都要重新加载,重新解析,可以用于复杂类型
 

elasticsearch脚本是一种用于操作和处理elasticsearch数据的脚本语言。在elasticsearch中,有两种类型的脚本,即inline script和stored script。inline script是在API请求时使用的脚本,而stored script是存储在elasticsearch中供后续使用的脚本。其中,painless是elasticsearch在升级到5.0版本之后新增的脚本语言,主要针对性地优化了elasticsearch的场景。它支持Java的静态类型和lambda表达式,使得对elasticsearch数据的操作更加轻量和快速,同时也更加简单和安全。painless脚本可以类比于SQL查询语句和存储过程,它的使用可以提高elasticsearch的灵活性和可扩展性。 需要注意的是,不同版本的elasticsearch可能会有不同的脚本语法和特性,因此如果想要深入学习elasticsearch脚本的操作,官方文档是最好的学习资料。您可以访问elasticsearch官方文档的地址https://www.elastic.co/guide/en/elasticsearch/painless/7.9/painless-guide.html,了解更多关于painless脚本的详细信息。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Elasticsearch 开机自启脚本](https://download.csdn.net/download/weixin_40344051/12922702)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Elasticsearch painless脚本教程(包含Java API和SpringDataElasticsearch调用脚本)](https://blog.csdn.net/qq_29864051/article/details/130250460)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值