<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Elasticsearch 如何實現(xiàn)時間差查詢?

          共 8250字,需瀏覽 17分鐘

           ·

          2022-06-21 15:32

          1、Elasticsearch 線上實戰(zhàn)問題

          問個問題啊,es能通過兩個字段差值進行查詢嗎?類似select * from myindex where endtimes- starttime > 10這種?

          ——問題來源:死磕Elasticsearch 知識星球

          那么問題來了,Elasticsearch 如何實現(xiàn)時間差的查詢呢?

          2、先說一下 MySQL 實現(xiàn)

          2.1 MySQL 表結(jié)構(gòu)

          2.2 MySQL 樣例數(shù)據(jù)

          2.3 MySQL 計算時間差?

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

          結(jié)果如下:

          結(jié)果 15 代表 15 分鐘的意思。

          3、Elasticsearch 實現(xiàn)拆解

          3.1 創(chuàng)建索引

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

          3.2 插入數(shù)據(jù)

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

          3.3 方案一:直接類MySQL 查詢實現(xiàn)

          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 預(yù)處理空間換時間實現(xiàn)

          核心使用的是:painless 無痛腳本。在對時間的腳本處理上略顯笨拙(大家有好的方法可以交流)。

          • 步驟1:時間字段轉(zhuǎn)成字符串;
          • 步驟2:字符串轉(zhuǎn)成 ZonedDateTime 字段類型;
          • 步驟3:ZonedDateTime 字段類型轉(zhuǎn)成 long 長整形。
          • 步驟4:求解兩個整形之差就可以了。

          實現(xiàn)如下代碼所示:

          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 的實現(xiàn)完全可以轉(zhuǎn)換為預(yù)處理+setting環(huán)節(jié)的 default_pipeline 方式實現(xiàn),確保寫入環(huán)節(jié)直接生成span字段值,確保候選實現(xiàn)空間換時間,提高檢索效率。

          default_pipeline 實現(xiàn)如下:

          PUT test-20220619-10-02
          {
            "settings": {
              "default_pipeline""my_pipeline_20220618"
            },
            "mappings": {
              "properties": {
                "start_time": {
                  "type""date"
                },
                "end_time": {
                  "type""date"
                }
              }
            }
          }


          ### 步驟2:導(dǎo)入數(shù)據(jù)
          PUT test-20220619-10-02/_doc/1
          {
            "start_time""2022-01-01T12:00:30Z",
            "end_time""2022-01-01T12:15:30Z"


          ### 方案二優(yōu)勢地方:時間差值已經(jīng)成為我們新的字段,直接用這個字段
          POST test-20220619-10-02/_search
          {
            "query": {
              "range": {
                "span": {
                  "gte": 15
                }
              }
            }
          }

          如上實現(xiàn),更簡潔寫法如下:

          PUT _ingest/pipeline/my_pipeline_20220618_03
          {
            "processors": [
              {
                "script": {
                  "lang""painless",
                  "source""""
                  
                    // create a Instant object
                  Instant start_instant = Instant.parse(ctx.starttime);
           
                  // get millisecond value using toEpochMilli()
                  long start_millisDateTime = start_instant.toEpochMilli();
                  
                  // create a Instant object
                  Instant 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 實時檢索實現(xiàn)

          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)"
                }
              }
            }
          }

          核心:同樣是轉(zhuǎn)化為毫秒,然后做的計算。

          注意:fields 要設(shè)置,否則數(shù)據(jù) _source 下不顯示。

          4、小結(jié)

          關(guān)于 Elasticsearch 實現(xiàn)時間差查詢,本文給出三種不同方案實現(xiàn),視頻解讀如下。

          從簡潔程度推薦方案 1 或者方案 3。

          從性能角度推薦方案 2 ——空間換時間,方案 2 可以優(yōu)化為寫入的時候指定 default_pipeline 全部預(yù)處理實現(xiàn)。

          你的業(yè)務(wù)環(huán)境有沒有遇到類似問題,你是如何實現(xiàn)的呢?

          參考

          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. 如何系統(tǒng)的學(xué)習(xí) Elasticsearch ?

          4. Elasticsearch 預(yù)處理沒有奇技淫巧,請先用好這一招!

          5. Elasticsearch的ETL利器——Ingest節(jié)點

          短時間快習(xí)得多干貨!

          和全球 1600+ Elastic 愛好者一起精進!


          比同事搶先一步學(xué)習(xí)進階干貨
          瀏覽 52
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  一级做a爰久久 | 亚洲精品久久久 | 91九色啦| 黑人久久久久 | 国产高清视频在线播放 |