当前位置: 首页 > article >正文

ElasticSearch系列:利用runtime field实现日期字符串实现日期范围查询

        在Elasticsearch中,如果你有一个时间字符串字段,并且你希望在查询时将其转换为date类型以便进行日期范围查询或其他日期相关的操作,你可以使用runtime_fields来实现这一转换。不过,与转换为UNIX时间戳不同,Elasticsearch的runtime_fields并不直接支持将字符串转换为date类型的字段,因为date类型通常需要在索引时就被正确映射。

        然而,你可以通过一种间接的方式来实现这一需求:在查询时,使用脚本将时间字符串解析为日期,并以某种形式(如UNIX时间戳或ISO 8601格式的字符串)返回,然后在查询逻辑中使用这个解析后的日期。虽然这不会改变原始字段的映射,但它允许你在查询时以日期的方式处理这个字段。

        那该如何在runtime_fields中使用脚本将时间字符串解析为ISO 8601格式的日期字符串,并在查询中使用这个日期呢?以 test_index索引为例。

put test_index
{
  "mappings": {
      "properties": {
        "id": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        },
        "name": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        },
        "num": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        },
        "t0": {
          "type": "date",
          "format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
        },
        "t2": {
          "type": "text",
          "fields": {
            "keyword": {
              "type": "keyword",
              "ignore_above": 256
            }
          }
        },
        "t3": {
          "type": "long"
        }
      }
    }
  
}

PUT test_index/_doc/index_1
{
  "id": "1",
  "name": "w1",
  "num": "9",
  "t0": "2024-12-17 14:04:10",
  "t2": "2024-12-17 14:04:59",
  "t3": 1734418709
}
PUT test_index/_doc/index_2
{
  "id": "2",
  "name": "w2",
  "num": "3",
  "t0": "2024-12-17 14:24:10",
  "t2": "2024-12-17 14:24:59",
  "t3": 1734420689
}
PUT test_index/_doc/index_3
{
  "id": "3",
  "name": "w3",
  "num": "9",
  "t0": "2024-12-17 14:28:10",
  "t2": "2024-12-17 14:28:59",
  "t3": 1734420721
}
PUT test_index/_doc/index_4
{
  "id": "4",
  "name": "w4",
  "num": "23",
  "t0": "2024-12-17 14:32:10",
  "t2": "2024-12-17 14:32:59",
  "t3": 1734420750
}

        从上面数据看,t2这个字段存储的日期是字符串类型的,如果想对这个t2这个日期进行范围查询呢?

GET /test_index/_search
{
  "fields" : ["*"],
  "query": {
    "range": {
		"t2": {
		  "gte": "2024-12-17T14:24:58Z",
		  "lte": "2024-12-17T15:29:58Z"
		}
	}
    
  }
}

        这时就用到了runtime_mappings。

GET /test_index/_search
{
  "fields" : ["*"],
  "runtime_mappings": {
    "t2_runtime": {
      "type": "keyword", // 使用keyword类型存储解析后的日期字符串
      "script": {
        "lang": "painless",
        "source": """
          String dateStr = params._source.t2;
          DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
          LocalDateTime dateTime = LocalDateTime.parse(dateStr, formatter);
          // 转换为ISO 8601格式并输出
          String isoDate = dateTime.atZone(ZoneId.of("UTC")).toInstant().toString();
          emit(isoDate);
        """
      }
      
    }
  },
  "query": {
    "range": {
		"t2_runtime": {
		  "gte": "2024-12-17T14:24:58Z",
		  "lte": "2024-12-17T15:29:58Z"
		}
	}
  }
}

在这个示例中:

  • t2是索引中存储时间字符串的字段名。
  • t2_runtime是定义的runtime_field,它将存储解析后的ISO 8601格式的日期字符串。
  • 脚本使用Painless语言,并且使用Java的DateTimeFormatterLocalDateTime类来解析时间字符串,并将其转换为ISO 8601格式的字符串。
  • 查询部分使用range查询来查找特定日期范围内的文档。
  • 注意时区

        请注意,这个示例中的日期格式("yyyy-MM-dd HH:mm:ss")和时区(UTC)应该根据实际数据进行调整。如果时间字符串格式不同,你需要相应地修改DateTimeFormatter的模式。另外,由于runtime_fields是在查询时动态计算的,因此它们可能会影响查询性能,特别是在大数据集上。

        如果发现性能受到影响,或者需要更复杂的日期处理逻辑(比如时区转换、不同的日期格式等),就需要考虑在索引数据之前就将时间字符串转换为正确的date类型,并在索引映射中正确配置这个字段。


未完待续。。。


http://www.kler.cn/a/442683.html

相关文章:

  • STM32 FreeRTOS 的任务挂起与恢复以及查看任务状态
  • 【update 更新数据语法合集】.NET开源ORM框架 SqlSugar 系列
  • 对MySQL滴MVCC理解(超详细)
  • 探索图像编辑的无限可能——Adobe Photoshop全解析
  • 《自动驾驶与机器人中的SLAM技术》ch9:自动驾驶车辆的离线地图构建
  • 优化神马关键词排名原理(优化神马搜索引擎关键词排名规则)
  • 使用Idea自带的git功能进行分支合并
  • 爬虫数据能用于商业吗?
  • linux下的单例安全的线程池实现
  • Android 之永乐大典
  • redis 缓存使用
  • uniapp打包apk允许横屏竖屏内容翻转
  • 【计算机网络2】计算机网络的性能能指标
  • 深入解析 `DataFrame.groupby` 和 `agg` 的用法及使用场景
  • VScode MAC按任意键关闭终端 想要访问桌面文件
  • Unity3D Shader变体自定义组合压缩方案详解
  • Next.js搜索引擎优化:如何利用React和Next.js解决SEO问题
  • RequestContextHolder 与 HttpServletRequest 的联系
  • The Rise and Potential of Large Language ModelBased Agents:A Survey---讨论
  • 博弈论3:图游戏SG函数(Graph Games)
  • 使用 MyBatis-Plus Wrapper 构建自定义 SQL 查询
  • Spark内存都消耗在哪里了?
  • PHP与AJAX:实现动态网页的完美结合
  • 浏览器事件循环机制
  • PostgreSQL约束延迟生效
  • 消除图片中的浅色水印