1、Elasticsearch 线上实战问题

问个问题啊,es能通过两个字段差值进行查询吗?类似select * from myindex where endtimes- starttime > 10这种?

——问题来源:死磕Elasticsearch 知识星球

那么问题来了,Elasticsearch 如何实现时间差的查询呢?

2、先说一下 MySQL 实现

2.1 MySQL 表结构

2.2 MySQL 样例数据

2.3 MySQL 计算时间差?

select timestampdiff(MINUTE, start_time, end_time) as span from test;

结果如下:

结果 15 代表 15 分钟的意思。

3、Elasticsearch 实现拆解

3.1 创建索引

PUT test-index-001
{"mappings": {"properties": {"starttime": {"type": "date"},"endtime": {"type": "date"}}}
}

3.2 插入数据

POST test-index-001/_bulk
{"index":{"_id":1}}
{"starttime":"2022-06-08T10:00:00Z","endtime":"2022-06-08T10:15:00Z"}

3.3 方案一:直接类MySQL 查询实现

POST test-index-001/_search
{"query": {"bool": {"filter": {"script": {"script": {"source": "doc['endtime'].date.minuteOfDay - doc['starttime'].date.minuteOfDay >= 15","lang": "expression"}}}}}
}

解读一下:

lang 指的是脚本语言,这里使用的是:expression,不是 painless 无痛脚本,所以写法和往常会不同。

更多推荐查看:

3.4 方案二:ingest 预处理空间换时间实现

核心使用的是:painless 无痛脚本。在对时间的脚本处理上略显笨拙(大家有好的方法可以交流)。

  • 步骤1:时间字段转成字符串;

  • 步骤2:字符串转成 ZonedDateTime 字段类型;

  • 步骤3:ZonedDateTime 字段类型转成 long 长整形。

  • 步骤4:求解两个整形之差就可以了。

实现如下代码所示:

PUT _ingest/pipeline/my_pipeline_20220618
{"processors": [{"script": {"lang": "painless","source": """String start_datetime = ctx.starttime; ZonedDateTime start_zdt = ZonedDateTime.parse(start_datetime); String end_datetime =ctx.endtime; ZonedDateTime end_zdt = ZonedDateTime.parse(end_datetime); long start_millisDateTime = start_zdt.toInstant().toEpochMilli();long end_millisDateTime = end_zdt.toInstant().toEpochMilli();long elapsedTime = end_millisDateTime - start_millisDateTime;ctx.span = elapsedTime/1000/60;"""}}]
}POST test-index-001/_update_by_query?pipeline=my_pipeline_20220618
{"query": {"match_all": {}}
}POST test-index-001/_search
{"query": {"range": {"span": {"gte": 15}}}
}

如上 update_by_query 的实现完全可以转换为预处理+setting环节的 default_pipeline 方式实现,确保写入环节直接生成span字段值,确保候选实现空间换时间,提高检索效率。

default_pipeline 实现如下:

PUT test-20220619-10-02
{"settings": {"default_pipeline": "my_pipeline_20220618"},"mappings": {"properties": {"start_time": {"type": "date"},"end_time": {"type": "date"}}}
}### 步骤2:导入数据
PUT test-20220619-10-02/_doc/1
{"start_time": "2022-01-01T12:00:30Z","end_time": "2022-01-01T12:15:30Z"
} ### 方案二优势地方:时间差值已经成为我们新的字段,直接用这个字段
POST test-20220619-10-02/_search
{"query": {"range": {"span": {"gte": 15}}}
}

如上实现,更简洁写法如下:

PUT _ingest/pipeline/my_pipeline_20220618_03
{"processors": [{"script": {"lang": "painless","source": """// create a Instant objectInstant start_instant = Instant.parse(ctx.starttime);// get millisecond value using toEpochMilli()long start_millisDateTime = start_instant.toEpochMilli();// create a Instant objectInstant end_instant= Instant.parse(ctx.endtime);// get millisecond value using toEpochMilli()long end_millisDateTime = end_instant.toEpochMilli();long elapsedTime = end_millisDateTime - start_millisDateTime;ctx.span = elapsedTime/1000/60;"""}}]
}

3.5 方案三:runtime_field 实时检索实现

POST test-index-001/_search
{"fields": ["*"],"runtime_mappings": {"span_value": {"type": "long","script": {"source": "emit((doc['endtime'].getValue().toInstant().toEpochMilli() - doc['starttime'].getValue().toInstant().toEpochMilli())/60000)"}}}
}

核心:同样是转化为毫秒,然后做的计算。

注意:fields 要设置,否则数据 _source 下不显示。

4、小结

关于 Elasticsearch 实现时间差查询,本文给出三种不同方案实现,视频解读如下。

从简洁程度推荐方案 1 或者方案 3。

从性能角度推荐方案 2 ——空间换时间,方案 2 可以优化为写入的时候指定 default_pipeline 全部预处理实现。

你的业务环境有没有遇到类似问题,你是如何实现的呢?

参考

https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-expression.html

https://www.elastic.co/guide/en/elasticsearch/reference/5.0/modules-scripting-expression.html#datefield_api

https://www.elastic.co/guide/en/elasticsearch/painless/master/painless-datetime.html#_datetime_input_from_an_indexed_document

https://www.elastic.co/guide/en/elasticsearch/painless/current/painless-api-reference-shared-java-time.html

推荐阅读

  1. 如何从0到1打磨一门 Elasticsearch 线上直播课?

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

  3. 如何系统的学习 Elasticsearch ?

  4. Elasticsearch 预处理没有奇技淫巧,请先用好这一招!

  5. Elasticsearch的ETL利器——Ingest节点

更短时间更快习得更多干货!

和全球 1600+ Elastic 爱好者一起精进!

比同事抢先一步学习进阶干货!

Elasticsearch 如何实现时间差查询?相关推荐

  1. java操作es聚合操作并显示其他字段_java使用elasticsearch分组进行聚合查询过程解析...

    这篇文章主要介绍了java使用elasticsearch分组进行聚合查询过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 java连接elas ...

  2. 【Elasticsearch】ElasticSearch里面的偏好查询

    1.概述 转载:ElasticSearch里面的偏好查询 在es查询的时候我们可以控制Preference,来完成特定shard或节点上的数据查询,默认情况下查询是随机的. 假如现在我们有一份索引5个 ...

  3. 【Elasticsearch】改进布尔查询的搜索相关性

    1.概述 翻译:Improving search relevance with boolean queries 有人翻译:Elasticsearch:使用布尔查询提高搜索的相关性 当你在Elastic ...

  4. 【Elasticsearch】Elasticsearch Span Query跨度查询

    1.概述 转载:Elasticsearch Span Query跨度查询 ES基于Lucene开发,因此也继承了Lucene的一些多样化的查询,比如本篇说的Span Query跨度查询,就是基于Luc ...

  5. 初识ElasticSearch(2) -文档查询之match查询 | 分词器

    1. 分词器: 2. match查询: 2.1. 数据准备 - 创建带分词器的索引映射 2.2. 数据准备 - 添加文档 2.3. 数据准备 - 查看文本分词 2.4. 查询 - 映射有分词器的字段查 ...

  6. Elasticsearch(es) 查询语句语法详解

    Elasticsearch 查询语句采用基于 RESTful 风格的接口封装成 JSON 格式的对象,称之为 Query DSL.Elasticsearch 查询分类大致分为全文查询.词项查询.复合查 ...

  7. ElasticSearch使用(嵌套查询、嵌套高亮)

    ElasticSearch使用(嵌套查询.嵌套高亮) 嵌套查询 bool 查询 must.should关系 1.只有must 2.只有should 3.must和should同时存在 4.怎样设置sh ...

  8. SpringBoot+Mybatis+Elasticsearch 实现模糊分页查询并标记关键字

    SpringBoot 整合 Elasticsearch 实现模糊分页查询并标记关键字 一.概述 & 介绍 Elasticsearch 是基于 Lucense 技术的搜索引擎(服务器),将数据进 ...

  9. 跟乐乐学ES!(三)ElasticSearch 批量操作与高级查询

    上一篇文章:跟乐乐学ES!(二)ElasticSearch基础. 下一篇文章:跟乐乐学ES!(四) java中ElasticSearch客户端的使用. 批量操作 有些增删改查操作是可以进行批量操作的, ...

最新文章

  1. 谈谈Python那些不为人知的冷知识(一)
  2. XGBoost算法原理解释(转载)
  3. 网络编程(发送get和post请求到服务器端,并获取响应)
  4. 大数据精准营销:买水培栀子花该推送啥
  5. 学习笔记(十九)——Python与数据库交互(mysql、redis)
  6. Codeforces 1106F Lunar New Year and a Recursive Sequence (线性代数、线性递推、数论、BSGS、扩展欧几里得算法)...
  7. 浮动div 内部元素 垂直居中
  8. mysql添加联合主键
  9. elman神经网络 python实现_Rust 能取代 Python,更好的实现神经网络?
  10. java rtmp录制视频_red5-rtmp-push
  11. 2018 最新 cnki账号 中国知网账号 帐号 免费入口 用户名 密码 万方 维普
  12. mysql insert on duplicate_一条Insert on duplicate引发的血案
  13. CSS-浏览器缩放使边框大小改变,导致布局改变的问题
  14. 10_放置街灯(Placing Lampposts,UVa 10859)
  15. NEW RDSP MODE I (模拟,循环节)
  16. 【软考-软件设计师】(五).计算机网络
  17. 超级计算机作文650字,努力初中作文650字(通用11篇)
  18. 计算机博士论文 评阅意见,博士论文评阅意见
  19. 交通·未来第2期:深度交通感知: 从区域流量预测到在线OD预测
  20. BZOJ 3573 [HNOI2014]米特运输

热门文章

  1. DVR/NVR解决方案
  2. Atcoder 4244 AtCoder Express 2 暴力
  3. Squirrel中的类与实例
  4. goahead - 环境准备和基本使用
  5. SVN:客户端与服务器端安装、配置与使用
  6. 什么是python 包_什么是python包
  7. [Python3]pandas.merge用法详解
  8. telnet 访问80端口
  9. 使用微软官方工具制作Windows10的U盘启动盘
  10. 《WinForm开发系列之控件篇》Item2 BindingNavigator