20

两个 Elasticsearch 线上实战问题及解读

 3 years ago
source link: https://mp.weixin.qq.com/s?__biz=MzI2NDY1MTA3OQ%3D%3D&%3Bmid=2247485452&%3Bidx=1&%3Bsn=a82bfd8d820defa8bf1a63127717d4df
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

线上实战问题 1

1、知识点

脚本的使用

2、问题描述:

你好,我想问一下,在 ES 里我想把两个字段的值是一样的查出来。

但是其中一个字段是在一个字典里的,我该怎么写啊?

{
"query": {
"bool": {
"must": {
"script": {
"script": {
"source": "doc['user_id']= doc['music.sec_uid']",
"lang": "painless"
}
}
}
}
}
}

比如:我想要查询 user_id 和 sec_uid 一样的数据,但是 sec_uid 是在 music 字典里。

我怎么处理呢?

3、问题分析

需求 核心 是:比较两个字段,把不同字段值相同的数据取出来。

这个时候,要想到传统的精准匹配搜索或者全文检索搜索都不能解决问题。

需要更高阶的搜索才可以,此时脑子里要快速过文档,当然也可以与查看文档相结合。

逐步定位文档的位置:

AZnY3ia.png!mobile

研读官方给出的 Demo,基本就能得到问题的答案。

这里会引申出一个非常重要的知识点,也是实战业务场景反馈最多的检索性能优化特别注意的点:

使用脚本可能会降低搜索速度。

正如官方文档解读:

  • 脚本无法利用Elasticsearch的倒排索引结构或相关优化。有时这可能会导致搜索速度降低。

  • 如果您经常使用脚本来转换索引数据,则可以通过在摄取期间(数据写入前通过 Ingest 管道方式)进行这些更改来加快搜索速度。但是,这通常意味着较慢的索引速度(数据写入速度)。

4、实战解答

PUT test_002
{
"mappings": {
"properties": {
"user_id": {
"type": "keyword"
},
"music": {
"properties": {
"sec_uid": {
"type": "keyword"
}
}
}
}
}
}

GET test_002/_mapping

POST test_002/_bulk
{"index":{"_id":1}}
{"user_id":333,"music.sec_uid":444}
{"index":{"_id":2}}
{"user_id":333,"music.sec_uid":333}
{"index":{"_id":3}}
{"user_id":333,"music.sec_uid":555}


POST test_002/_search
{
"query": {
"bool": {
"filter": [
{
"script": {
"script": {
"source":"doc['user_id']==doc['music.sec_uid']",
"lang":"painless"
}
}
}
]
}
}
}

线上实战问题 2

1、知识点

update_by_query,  ingest 数据预处理 + painless 脚本的使用

2、问题描述

update脚本,某个时间字段time,都是 2020-08-10 xx:xx:xx, 如何将该字段所有值替换为2020-10-24 xx:xx:xx, 只改日期,不改时分秒。

咋写呢?求大佬们指点啊

3、问题分析

需求核心是:

  • 批量更新

脑海里里面映射出:update_by_query

  • 基于特定值的一部分更新

脑海里马上映射出:painless 脚本处理

  • 脚本实现选型

选型 1:直接 update_by_query 结合 painless

选型 2:update_by_query 结合 inges t结合 painless 脚本处理

我个人倾向于ingest,个人感觉语法相对友好。

逐步定位文档的位置:

nYJR3eY.png!mobile

研读官方给出的Demo,结合拆解的需求,基本就能得到问题的答案。

注意 :Ingest 是后来版本的新特性,但到了7.X版本,也已经有很长时间了。大家用的少,但的确非常重要,建议要多用、常用常新!

4、实战解答(非最优解)

注意:以下是示例DSL。

PUT my_index
{
"mappings": {
"properties": {
"date": {
"type": "keyword"
}
}
}
}

PUT my_index/_doc/2
{
"date": "2015-01-01T12:10:30Z"
}



PUT _ingest/pipeline/my_pipeline
{
"description": "use index:my-index",
"processors": [
{
"script": {
"lang": "painless",
"source": "ctx.data_new = ctx.date.replace('2015-01-01', '2020-01-01')"
}
}
]
}

POST my_index/_update_by_query?pipeline=my_pipeline
{
"query":{
"match_all":{}
}
}

GET my_index/_search

小结

遇到问题不要慌,

拆解问题来帮忙。

拆解之后找文档,

结合文档和拆解的需求,

问题自然迎刃而解。

通过拆解问题,得到遇到类似问题的应对策略和方法论比什么都重要!

大家对问题又不同见解或者花式解法,欢迎留言交流。

更多 推荐:

重磅 | 死磕 Elasticsearch 方法论认知清单(2020年国庆更新版)

能拿驾照就能通过 Elastic 认证考试!

fyQ3mqI.png!mobile

短时间 快习得 多干货!

中国 40%+  Elastic 认证工程师出自于此!

全球   800+  Elastic 爱好者一起死磕 Elasticsearch!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK