您的位置:首页 > 健康 > 养生 > 3c渠道网_广州疫情最新数据消息_衡阳百度推广公司_百度一下知道首页

3c渠道网_广州疫情最新数据消息_衡阳百度推广公司_百度一下知道首页

2024/10/6 17:44:49 来源:https://blog.csdn.net/qq_32880923/article/details/142684368  浏览:    关键词:3c渠道网_广州疫情最新数据消息_衡阳百度推广公司_百度一下知道首页
3c渠道网_广州疫情最新数据消息_衡阳百度推广公司_百度一下知道首页

文章目录

      • 0. 前言
      • 1. 基本使用
      • 2. 读请求中访问文档字段
        • 2.1 遍历 List
        • 2.2 判断对象存不存在
        • 2.3 判断值是否为空
        • 2.4 总结
      • 3. 写请求中访问文档字段
        • 3.1 数字相加
        • 3.2 字符串相加
        • 3.3 将字符串转为数组

0. 前言

在前面部分,我们介绍了 ES 的基本使用和要掌握的基础性读写原理。
从本章开始,会开始介绍 ES 进阶使用。
本章要介绍的内容是 Script 的基本使用。
在日常开发中,读请求很少会用,写请求会使用比较多。
在读请求、写请求中,Script 访问文档值的方式有所不同,下面我将对 Script 在读写请求中使用进行介绍。

1. 基本使用

我们来看一个修改算分的例子。

写入文档

PUT test_18/_doc/1
{"counter": 1,"tags": ["red"],"scores": [1,2,3,4,5]
}

查询时,修改算分

GET test_18/_search
{"query": {"script_score": {"query": {"term": {"tags": "red"}},"script": {"lang": "painless","source": "Math.log(_score * 2) + params['my_modifier'] * doc['counter'].value","params": {"my_modifier": 2}}}}
}

script_score 是 ES 用于修改算分的查询,当然这不是我们的重点。

script 中包含 3 个属性

  • lang: 默认为 painless,非必填
  • source: 脚本,必填
  • params: 传递给脚本的参数,没有定义参数时,不用填

可以看到,在 Script 中我们可以使用 JAVA Api, 可以访问自定义的参数, 可以访问 ES 文档字段值。

2. 读请求中访问文档字段

painless script language 其实跟 JAVA 语法大相径庭。你可以简单认为就是在写 JAVA 代码。

在读请求中,ES 将文档映射为名为 doc 的 map。可以通过 doc['字段名'] 访问对应字段的对象。

2.1 遍历 List
GET test_18/_search
{"query": {"script_score": {"query": {"match_all": {}},"script": {"lang": "painless","source": """int total = 0;for (int i = 0; i < doc['scores'].length; ++i) {total += doc['scores'][i];}return total;"""}}}
}

代码解释

  • doc['scores'] 获取到文档对象,即 scores 字段
  • .lengthJAVA 数组的方法
  • doc['socere'][i] 访问数组中具体的值

script 中不允许访问 text 字段

GET test_18/_search
{"query": {"function_score": {"script_score": {"script": {"lang": "painless","source": """int total = 0;for (int i = 0; i < doc['tags.keyword'].length; ++i) {total += doc['counter'].value;}return total;"""}}}}
}

代码解释

  • doc['tags.keyword'],拿到 tags.keyword 对象。需要特别注意,这里不能使用 doc['tags']因为 ES 在 script 中不允许访问 text 字段
  • doc['counter'],获取 counter 对象。.value 获取 counter 对象的值
2.2 判断对象存不存在

doc.containsKey['field']

GET test_18/_search
{"query": {"script_score": {"query": {"match_all": {}},"script": {"lang": "painless","source": """int total = 0;if (doc.containsKey('goals')) {return doc['goals'].value;} else {return (int)_score;}"""}}}
}

代码解释

  • doc.containsKey('goals'): 判断是否包含 goals key。之前我们说过的。文档会被映射为一个 map。因此 doc 具备 map 的函数。
  • return (int)_score: _scorescript_score 中是一个特殊字段。(int) 是类型强转,和 JAVA 语法一致
2.3 判断值是否为空

doc['field'].size()

GET test_18/_search
{"query": {"script_score": {"query": {"match_all": {}},"script": {"lang": "painless","source": """int total = 0;if (doc['counter'].size() == 0) {return 3;} else {return 2;}"""}}}
}

代码解释

  • doc['counter'].size() 获取 counter 对象长度
2.4 总结
  1. 读请求中,可以使用 doc['字段名'] 访问对应字段的对象
  2. script 读请求中,无法访问 text 字段
  3. painless 语法与 JAVA 语法类似
  4. 关于 painless 更多可阅读 ES painless 官网
  5. painless 中可以使用哪些 API,可以参考 painless 支持的 API 文档

3. 写请求中访问文档字段

在写请求中使用脚本,我们大部分情况下是结合 Ingest Pipeline 一起使用。
Ingest pipeline 中,通过 ctx.xxx 就可以访问到文档字段。

注:Ingest pipeline:可以在文档写入前对文档进行预处理。

下面,我们来看几个例子

3.1 数字相加

将 math_score + verbal_score 赋值给 total_score

创建索引

PUT test_18_write_01
{"mappings": {"properties": {"math_score": {"type": "integer"},"verbal_score": {"type": "integer"},"total_score": {"type": "integer"}}}
}

创建 ingest pipeline

PUT _ingest/pipeline/test_18_write_01_pipeline
{"description": "Calculates the total test score","processors": [{"script": {"source": "ctx.total_score = (ctx.math_score + ctx.verbal_score)"}}]
}

写入时,指定 pipeline

PUT test_18_write_01/_doc/1?pipeline=test_18_write_01_pipeline
{"math_score": 99,"verbal_score": 89
}

查看结果

GET test_18_write_01/_search

在这里插入图片描述

已经为我们自动写入了 total_score

3.2 字符串相加

将 lastName、firstName 相加,赋值给 fullName

创建 ingest pipeline

PUT _ingest/pipeline/test_18_write_02_pipeline
{"description": "String concatenation test","processors": [{"script": {"source": """if (ctx.containsKey('lastName') && ctx.containsKey('firstName')) {ctx.fullName = ctx.lastName + ' ' + ctx.firstName;}"""}}]
}

写入文档,并指定 pipeline

PUT test_18_write_02/_doc/1?pipeline=test_18_write_02_pipeline
{"firstName": "hello","lastName": "elasticsearch"
}
3.3 将字符串转为数组

将 name 转换为数组,并赋值给 names

创建 pipeline

PUT _ingest/pipeline/test_18_write_03_pipeline
{"description": "string to array","processors": [{"script": {"source": """ctx.names = ctx.name.splitOnToken(',')"""}}]
}

写入数据,并指定 pipeline

PUT test_18_write_03/_doc/1?pipeline=test_18_write_03_pipeline
{"name": "hello,elasticsearch"
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com