[ElasticSearch 8 learning and teaching] 04. Scripting operation of ElasticSearch 8

Article directory

  • Preface
  • 1. Painless script
    • 1.1 Features
    • 1.2 Basic syntax
      • 1.2.1 Update data
        • 1.2.1.1 Ordinary update of fields
        • 1.2.1.2 Field condition update
        • 1.2.1.3 Query and modify some field values
        • 1.2.1.3 Query using multiple scripts
        • 1.2.1.4 Execute script segment
  • 2. expression script
    • 2.1 Features
    • 2.2 Basic syntax
        • 2.2.1.1 Query and modify some field values
  • 3. Stored procedure
    • 4. Precautions
  • Summarize
  • Preview

Foreword

The previous article talked about the most basic CURD operation of ES. Today’s article mainly talks about ES< based on Scripting. /em> data.
First of all, we need to have a concept. What is Scripting operation? In fact, ES has a default scripting language that allows us to use RESTful API When doing so, use scripts with logic to complete more complex operations.

1. Painless script

1.1 Features

If you use the Painless script, it has the following advantages:
Fast performance: several times faster than alternatives.
Security: Fine-grained whitelisting with method call/field granularity.
Optional input: Variables and parameters can use explicit types or dynamic def types.
Syntax: Extend Java’s syntax with a subset of Groovy for ease of use.
Optimization: Designed specifically for Elasticsearch scripts.

To put it bluntly, it actually feels a bit like the stored procedures/functions in traditional relational databases, which are directly handed over to ES for processing, instead of doing a lot of operations on the business code yourself and then doing the usual thing. CURD API

1.2 Basic syntax

1.2.1 Update data

1.2.1.1 Normal update of fields
  1. For addition and subtraction of integer fields, the syntax reference is as follows:
POST my_index/_update/2
{<!-- -->
  //Age + 1
  "script": "ctx._source.age + =1"
}
//Or this
POST my_index/_update/3
{<!-- -->
  //Age + 1
  "script": {<!-- -->
  "source": "ctx._source.age + =1"
  }
}
  1. For array type data, you can do this:
POST my_index/_update/2
{<!-- -->
  //Add label
  "script": "ctx._source.hobbies.add('Skiing')"
}
//Or this
POST my_index/_update/3
{<!-- -->
  //Age + 1
  "script": {<!-- -->
  "lang": "painless", //Indicate the script language used, the default is painless
 "source": "ctx._source.hobbies.add('Billiards')"
  }
}
//If you use passing parameters
POST my_index/_update/3
{<!-- -->
  //Age + 1
  "script": {<!-- -->
 "lang": "painless", //Indicate the script language used, the default is painless
 "source": "ctx._source.hobbies.add(params.tag_name)",
 "params": {<!-- -->
 "tag_name":"Fitness"
 }
  }
}

There is something to note here, because the scripts in script.source will be cached, so if you query the same script repeatedly, the parameters passed will change frequently In this case, using parameter passing can greatly improve the execution speed of es.

1.2.1.2 Field condition update

Operations similar to insert or update are actually just adding the upsert keyword

{<!-- -->
  "script": {<!-- -->
"lang": "painless", //Indicate the script language used, the default is painless
"source": "ctx._source.hobbies.add(params.hobby_name)",
"params": {<!-- -->
"hobby_name":"Fitness"
}
  },
  "upsert": {<!-- -->
    "name": "Four little sheep",
  "hobbies": ["fitness", "swimming"]
  }
}
1.2.1.3 Query and modify some field values
//If you use parameter passing
GET my_index/_search
{<!-- -->
  //When querying, use script_fields.test_field
  "script_fields": {<!-- -->
 "test_field": {<!-- -->
 "script": {<!-- -->
 "lang": "expression",
 // If painless is used
 "source": "doc['price'].value*0.9"
 }
 }
  }
}
1.2.1.3 Query with multiple scripts
//If you use parameter passing
GET my_index/_search
{<!-- -->
  //When querying, use script_fields.test_field
  "script_fields": {<!-- -->
 "test_field": {<!-- -->
 "script": {<!-- -->
 "lang": "expression",
 // If painless is used
 "source": "[doc['price'].value*0.9, doc['price'].value*0.8], doc['price'].value*0.7 "
 }
 }
  }
}
1.2.1.4 Execute script segment

If you need to execute a large section of code, you can do this

GET my_index/_search
{<!-- -->
  "script_field":{<!-- -->
    "test_script":{<!-- -->
      "script": {<!-- -->
        "lang": "painless",
        "source": """
          ctx._source.name + = params.name;
          ctx._source.price + = params.price
        """,
        "params": {<!-- -->
          "price": 10,
          "name": "chen"
        }
      }
    }
  }
}

2. expression script

2.1 Features

Compared with painless, expression supports a smaller range, but its performance will be higher in certain scenarios, such as adding and subtracting certain fields during querying. Multiply and divide.

2.2 Basic syntax

2.2.1.1 Query and modify some field values
//If you use parameter passing
GET my_index/_search
{<!-- -->
  //When querying, use script_fields.test_field
  "script_fields": {<!-- -->
 "test_field": {<!-- -->
 "script": {<!-- -->
 "lang": "expression",
 // If painless is used
 "source": "doc['price'] * 0.9"
 }
 }
  }
}

3. Stored procedures

If you need long-term storage of the script, you can

POST _script/calc_discount
{<!-- -->
  "script":{<!-- -->
    "lang": "painless",
    "source": "doc['price'].value * params.discount"
  }
}

When using it, just check it like this

GET my_index/_search
{<!-- -->
  "test_script":{<!-- -->
    "script": {<!-- -->
      "id": "calc_discount",
      "params": {<!-- -->
        "discount": 0.7
      }
    }
  }
}

4. Precautions

  1. For time type fields, if you want to use functions related to the field in script, you need to omit the get prefix and use lowercase letters, such as createTime .value.mills
  2. The script supports regular expressions, but it is not recommended to use it because ES itself has a prevention mechanism for Painless scripts, which is to prevent the deep callback behavior of the script for a long time Loop behavior. If you use regular expressions, these defense mechanisms will be broken. To use regular expressions, you need to modify a certain value in the configuration file (elasticsearch.yml).
script.painless.regex.enabled: true

Summary

Preview

I was laid off by my previous company at the end of May 2023. I will publish relevant knowledge points one after another in October. The next article will briefly talk about Scripting query.

syntaxbug.com © 2021 All Rights Reserved.