Skip to main content
 首页 » 编程设计

Elasticsearch Scripting 教程

2022年07月19日118lyhabc

Elasticsearch Scripting 教程

Elasticsearch中最强大、有用的功能可能是其 Scripting 功能。通过脚本功能可以执行多种操作,如获取搜索请求的特定字段,修改、删除字段。本文学习如果通过脚本功能实现这些基本功能。

1. Elasticsearch Scripting介绍

Elasticsearch使用Painless或Java创建自定义表达式脚本。在5.x版本之后Painless作为默认版本。Painless更快、安全,比其他脚本语言更简单,语法与Java、groovy类似。

script作为请求主体的一个字段,其规范包括三个部分:

# the "script" field encompasses the main body of the JSON scripting request 
"script": { 
 
# scripting language name 
"lang": "painless", 
 
# source object (or document ID) as well as the operations performed by the script 
"source": "ctx._source = params.someNum", 
 
# the parameters or values for the script's operations 
"params": { "someNum = 12345" } 
} 
  • lang

指定语言,从v5.x之后默认为Painless

  • source及ctx变量

使用ctx变量访问文档的source,即:ctx._source
查询时使用doc[‘field_name’].value访问字段值。

GET /courses/_search 
{ 
  "query" : { 
        "match_all": {} 
  }, 
  "script_fields": { 
    "db_enrolled": { 
      "script": { 
        "source": "doc['students_enrolled'].value * params.interval", 
        "params": {"interval":2} 
      } 
    } 
  } 
} 

上面示例给返回文档增加db_enrolled字段,其值为students_enrolled字段值两倍。

  • params

用于给脚本设定参数,脚本中引用参数:params.name ,name表示参数名称。

2. 创建索引

POST /testscript/_create/1 
{ 
"personalDetails": { 
     "name": "bob", 
     "age": "13" 
   }, 
   "marks": { 
     "physics": 48, 
     "maths": 45, 
     "chemistry": 44 
   }, 
   "remarks": [ 
     "hard working", 
     "intelligent" 
   ] 
} 

查询id为1的记录:

GET /testscript/_doc/1 

返回内容:

{ 
  "_index" : "testscript", 
  "_type" : "_doc", 
  "_id" : "1", 
  "_version" : 1, 
  "_seq_no" : 1, 
  "_primary_term" : 1, 
  "found" : true, 
  "_source" : { 
    "personalDetails" : { 
      "name" : "bob", 
      "age" : "13" 
    }, 
    "marks" : { 
      "physics" : 48, 
      "maths" : 45, 
      "chemistry" : 44 
    }, 
    "remarks" : [ 
      "hard working", 
      "intelligent" 
    ] 
  } 
} 

3. 脚本更新文档

下面示例展示使用脚本更新文档的常用操作,主要包括:

  • 给索引增加新的字段
  • 更新已存在数组元素值
  • 删除数组元素
  • 删除字段

3.1. 给已存在字段增加新的属性

上面示例中包括三门课程成绩,现在我们增加英语的分数:

POST /testscript/_update/1 
{ 
  "script": "ctx._source.marks.english=41"   
} 
 

更新后记录已经改变,并且_version版本为2:

{ 
  "_index" : "testscript", 
  "_type" : "_doc", 
  "_id" : "1", 
  "_version" : 2, 
  "_seq_no" : 1, 
  "_primary_term" : 1, 
  "found" : true, 
  "_source" : { 
    "personalDetails" : { 
      "name" : "bob", 
      "age" : "13" 
    }, 
    "marks" : { 
      "physics" : 48, 
      "maths" : 45, 
      "chemistry" : 44, 
      "english" : 41 
    }, 
    "remarks" : [ 
      "hard working", 
      "intelligent" 
    ] 
  } 
} 

版本数表明文档的改变次数。

3.2. 更新已存在字段属性值

接着我们更新physics的成绩为49:

POST /testscript/_update/1 
{ 
  "script":{ 
    "source": "ctx._source.marks.physics=params.physics", 
    "params": {"physics":49} 
  } 
} 

验证结果:

{ 
  "_index" : "testscript", 
  "_type" : "_doc", 
  "_id" : "1", 
  "_version" : 3, 
  "_seq_no" : 2, 
  "_primary_term" : 1, 
  "found" : true, 
  "_source" : { 
    "personalDetails" : { 
      "name" : "bob", 
      "age" : "13" 
    }, 
    "marks" : { 
      "physics" : 49, 
      "maths" : 45, 
      "chemistry" : 44, 
      "english" : 41 
    }, 
    "remarks" : [ 
      "hard working", 
      "intelligent" 
    ] 
  } 
} 

physics的值为49,版本为3,和预期一致。

3.3. 删除字段属性

删除物理成绩:

POST /testscript/_update/1 
{ 
  "script":{ 
    "source": "ctx._source.marks.remove('physics')" 
  } 
} 

验证结果:

{ 
  "_index" : "testscript", 
  "_type" : "_doc", 
  "_id" : "1", 
  "_version" : 4, 
  "_seq_no" : 3, 
  "_primary_term" : 1, 
  "found" : true, 
  "_source" : { 
    "personalDetails" : { 
      "name" : "bob", 
      "age" : "13" 
    }, 
    "marks" : { 
      "maths" : 45, 
      "chemistry" : 44, 
      "english" : 41 
    }, 
    "remarks" : [ 
      "hard working", 
      "intelligent" 
    ] 
  } 
} 

已经没有了物理成绩,版本为4。

3.4. 删除整个字段

删除marks整个字段:

POST /testscript/_update/1 
{ 
  "script":{ 
    "source": "ctx._source.remove('marks')" 
  } 
} 

验证结果是否一致:

{ 
  "_index" : "testscript", 
  "_type" : "_doc", 
  "_id" : "1", 
  "_version" : 5, 
  "_seq_no" : 4, 
  "_primary_term" : 1, 
  "found" : true, 
  "_source" : { 
    "personalDetails" : { 
      "name" : "bob", 
      "age" : "13" 
    }, 
    "remarks" : [ 
      "hard working", 
      "intelligent" 
    ] 
  } 
} 

3.5. 增加数组元素

增加一条评论:

POST /testscript/_update/1 
{ 
  "script":{ 
    "source": "ctx._source.remarks.add('Love of learning')" 
  } 
} 

验证结果:

{ 
  "_index" : "testscript", 
  "_type" : "_doc", 
  "_id" : "1", 
  "_version" : 6, 
  "_seq_no" : 5, 
  "_primary_term" : 1, 
  "found" : true, 
  "_source" : { 
    "personalDetails" : { 
      "name" : "bob", 
      "age" : "13" 
    }, 
    "remarks" : [ 
      "hard working", 
      "intelligent", 
      "Love of learning" 
    ] 
  } 
} 

3.6. 删除数组元素

POST /testscript/_update/1 
{ 
  "script":{ 
    "lang": "painless", 
    "source": "ctx._source.remarks.remove(ctx._source.remarks.indexOf('Love of learning'))" 
  } 
} 

4. 总结

本文学习了使用Elasticsearch中脚本模块简易修改文档字段值。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/104287239
阅读延展