我们在实际的业务场景中做Elasticsearch开发时,免不了遇到这样、那样的问题。 《死磕Elasticsearch方法论》中,已经告诉大家相关问题的排查方法。 这一节,我们以具体的示例,解决基于业务场景的Elasticsearch难题的方法?
请问下es可以在date字段上查询月日吗 下单时间字段类型是date,想查询每年11月11日下单的记录?有什么办法可以zh直接查? 原文链接:https://elasticsearch.cn/question/3649
步骤1:脑海中显现:ES中有哪些数据类型?ES支持哪些数据类型。 此处,我个人认为,没必要记住。 但是,要知道,从哪里查? 记住,查询方法如下: 在Google或者Bing国际版输入:“elasticsearch data type” 相关链接:http://t.cn/REjyfxa
步骤2:ES中date字段时如何定义的? 在核心的数据类型部分,就介绍了ES中的Date类型: 数据类型分为三种: 1)字符串类型如: "2015-01-01" or "2015/01/01 12:10:30". 2)长整型,以毫秒度量:1520256456000 3)整型,以秒度量:1520256456。
1PUT my_index 2{ 3 "mappings": { 4 "_doc": { 5 "properties": { 6 "date": { 7 "type": "date", 8 "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis" 9 } 10 } 11 } 12 } 13}
步骤3:常见日期类型的检索方式: range时间区间检索:
1GET _search 2{ 3 "query": { 4 "range" : { 5 "timestamp" : { 6 "gte": "2015-01-01 00:00:00", 7 "lte": "now", 8 "time_zone": "+01:00" 9 } 10 } 11 } 12}
参考: http://t.cn/RcWM2Py
步骤4:如何获取日期中指定的年、月、日检索? 能想到的是什么呢——的确,我也没这么用过。 注意:此时一定要用英文去检索。 在Google或者Bing国际版或者Stackoverflow中输入:“elasticsearch date get month“。
看看网友的思路: 返回如下: http://t.cn/REjVkGW http://t.cn/REjfh8z
初步,确定解决方案。 结合:script检索+ getDate().getMonthOfYear()接口实现条件检索。
1、script检索 一种基于 Painless脚本语言的检索, Painless 脚本语言是简单、安全应用于Elasticsearch中的脚步语言。 应用举例:
1GET /_search 2{ 3 "query": { 4 "bool" : { 5 "must" : { 6 "script" : { 7 "script" : { 8 "source": "doc['num1'].value > 1", 9 "lang": "painless" 10 } 11 } 12 } 13 } 14 } 15}
2、时间的返回接口 getDate().getMonthOfYear()
注意: date.getMonthOfYear() == 11 返回11月; date.getDayOfMonth() == 11 返回11日。
基于之前的分析,我的思路: 第一步:获取月; 第二步:获取日; 第三步:二者与。
具体实现:
1POST index_*/_search 2{ 3 "size":100, 4 "_source": { 5 "includes": [ 6 "title", 7 "create_time" 8 ] 9 }, 10 "query": { 11 "bool" : { 12 "must" : [{ 13 "script" : { 14 "script" : { 15 "inline": "doc['create_time'].getDate().getMonthOfYear() == 12", 16 "lang": "painless" 17 } 18 } 19 }, 20 { 21 "script" : { 22 "script" : { 23 "inline": "doc['create_time'].getDate().getDayOfMonth() == 23", 24 "lang": "painless" 25 } 26 } 27 } 28 ] 29 } 30 } 31}
返回结果: 实际业务中,我以12月,23日作为检索条件验证的,我用的系统中没有11月11日的数据。
1{ 2 "took": 5, 3 "timed_out": false, 4 "_shards": { 5 "total": 5, 6 "successful": 5, 7 "failed": 0 8 }, 9 "hits": { 10 "total": 8536, 11 "max_score": 1, 12 "hits": [ 13 { 14 "_index": "bak_index_v3", 15 "_type": "bke_type", 16 "_id": "AWCEDIuUYGOEa9MAzRvk", 17 "_score": 1, 18 "_source": { 19 "create_time": "2017-12-23 23:45:02", 20 "title": "世界道学网-道学文摘-唱道真言" 21 } 22 }, 23 { 24 "_index": "bak_index_v3", 25 "_type": "bke_type", 26 "_id": "AWCD2bs4YGOEa9MAzRta", 27 "_score": 1, 28 "_source": { 29 "create_time": "2017-12-23 22:49:32", 30 "title": "新浪网-航天知识-飞向月球" 31 } 32 }, 33 { 34 "_index": "bak_index_v3", 35 "_type": "baike_type", 36 "_id": "AWB_uk1jYGOEa9MAzRs4", 37 "_score": 1, 38 "_source": { 39 "create_time": "2017-12-23 03:36:44", 40 "title": "3DXXX需求" 41 } 42 }, 43 { 44 "_index": "bak_index_v3", 45 "_type": "bke_type", 46 "_id": "AWCD2bhbYGOEa9MAzRtZ", 47 "_score": 1, 48 "_source": { 49 "create_time": "2017-12-23 22:49:31", 50 "title": "新浪网-知识-什么是全球定位系统" 51 } 52 } 53 ] 54 } 55}
参考:脚本检索——
http://t.cn/R3nxhwW
有没有更便捷的方法。 这里,后期检索的时候,发现如下不需要bool检索的更高效的解决方案: https://goo.gl/EhtJA2
核心的一行脚本: "script": "doc.ActivityDate.date.getMonthOfYear() == 12 && doc.ActivityDate.date.getDayOfMonth() == 9" 对应于我们的问题的解决方案:
1doc['create_time'].getDate().getMonthOfYear() == 11 2&& doc['create_time'].getDate(). getDayOfMonth () == 11
同时,这里告诉我们正确的英文关键词的搜索应该为: Elasticsearch Filtering part of date ignoring Year like SQL DATEPART function 你我共深思。
本文分享自微信公众号 - 铭毅天下(gh_0475cf887cf7),作者:铭毅天下
原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。
原始发表时间:2018-05-20
本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。
我来说两句