【Elasticsearch】实现气象数据存储与查询系统

🧑 博主简介:CSDN博客专家历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c=1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编程高并发设计Springboot和微服务,熟悉LinuxESXI虚拟化以及云原生Docker和K8s,热衷于探索科技的边界,并将理论知识转化为实际应用。保持对新技术的好奇心,乐于分享所学,希望通过我的实践经历和见解,启发他人的创新思维。在这里,我希望能与志同道合的朋友交流探讨,共同进步,一起在技术的世界里不断学习成长。
技术合作请加本人wx(注明来自csdn):foreast_sea

在这里插入图片描述


在这里插入图片描述

基于 Elasticsearch 的气象数据存储与查询系统:构建气象数据处理的强大引擎

一、引言

在当今科技飞速发展的时代,气象数据的收集、存储与分析对于气象研究、天气预报以及应对气候变化等诸多方面都具有极为关键的意义。气象部门每天都会通过各种先进的观测设备和技术手段,收集海量的气象数据,这些数据涵盖了气温气压湿度风速降水等多个重要的气象要素。

传统的气象数据处理方式在面对如此庞大且复杂的数据量时,逐渐暴露出诸多局限性。数据存储的效率、查询的速度以及分析的深度和广度都难以满足日益增长的气象研究和业务需求。而 Elasticsearch 的出现,为气象数据的管理带来了全新的解决方案。

Elasticsearch 是一个分布式高可用、实时的搜索与数据分析引擎,它基于 Lucene 构建,具备强大的全文搜索功能和高效的数据存储与检索能力。在气象领域,它能够轻松应对海量气象数据的存储挑战,通过其灵活且可定制的索引结构,使得气象数据可以被快速地组织和索引。气象工作人员可以利用 Elasticsearch 的丰富查询接口,迅速地从海量数据中提取出所需的气象信息,无论是特定时间段内的气温变化趋势,还是某一地区在历史上的极端气象事件记录,都能够在瞬间得到精准的查询结果。这不仅大大提高了气象数据的利用效率,还为气象预报员深入分析气象变化规律提供了有力的工具,从而能够更加准确地预测未来的天气状况,为农业生产航空航天交通运输等众多行业提供可靠的气象服务保障,助力人类更好地适应和应对气候变化带来的各种影响。

我们将深入探讨如何基于 Elasticsearch 构建气象数据存储与查询系统,详细介绍其中所涉及的技术细节、代码实现以及测试方法。

二、Elasticsearch 数据类型在气象数据中的应用

  1. 数值类型
    • 整数类型(如 long、integer 等):在气象数据中,许多数据可以用整数表示。例如,气压值通常在一定范围内,可以使用整数类型来存储。以百帕为单位的气压数据,一般在 900 到 1100 之间,使用 integer 类型就可以很好地容纳。
    • 浮点数类型(如 double、float 等):气温、湿度等数据可能包含小数部分,适合用浮点数类型存储。比如气温数据,可能精确到小数点后一位,像 25.5℃,使用 double 类型能够准确地记录这些数据。
  2. 日期类型(date):气象数据中的观测时间是非常重要的信息。例如,降水数据的记录必然关联着对应的时间点。通过 date 类型,可以方便地存储和处理这些时间信息,便于后续按照时间维度进行数据查询和分析,如查询某一天或某一时间段内的气象数据变化。
  3. 文本类型(keyword、text):对于一些气象站点的名称、地区名称等信息,可以使用 keyword 类型。keyword 类型适合存储结构化的文本数据,在查询时可以进行精确匹配。而对于一些气象现象的描述,如“暴雨”“大风”等,如果需要进行全文搜索和相关性分析,则可以使用 text 类型。

三、Elasticsearch 索引结构设计

  1. 索引名称:为气象数据创建一个专门的索引,例如“meteorological_data_index”。这个索引将作为所有气象数据存储和查询的基础容器。
  2. 映射(Mapping)
    • 对于气温数据字段,定义如下映射:
{"properties": {"temperature": {"type": "double"}}
}
  • 气压字段映射:
{"properties": {"pressure": {"type": "integer"}}
}
  • 湿度字段映射:
{"properties": {"humidity": {"type": "double"}}
}
  • 风速字段映射:
{"properties": {"wind_speed": {"type": "double"}}
}
  • 降水字段映射:
{"properties": {"precipitation": {"type": "double"}}
}
  • 观测时间字段映射:
{"properties": {"observation_time": {"type": "date","format": "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"}}
}
  • 气象站点名称字段映射:
{"properties": {"station_name": {"type": "keyword"}}
}

四、相关 Maven 依赖

在 Java 项目中使用 Elasticsearch,需要添加以下 Maven 依赖:

<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.17.9</version>
</dependency>
<dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>7.17.9</version>
</dependency>

这里使用的是 Elasticsearch 7.17.9 版本,其中elasticsearch-rest-high-level-client用于与 Elasticsearch 进行高级别的 REST 交互,elasticsearch核心库提供了基础的功能支持。

五、实现步骤

(一)连接到 Elasticsearch

import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;public class ElasticsearchConnection {private static final String HOST = "localhost";private static final int PORT = 9200;public static RestHighLevelClient getClient() {// 创建 HttpHost 对象,指定 Elasticsearch 服务器地址和端口HttpHost httpHost = new HttpHost(HOST, PORT, "http");// 创建 RestHighLevelClient 对象,用于与 Elasticsearch 进行交互return new RestHighLevelClient(RestClient.builder(httpHost));}
}

在上述代码中,首先定义了 Elasticsearch 服务器的主机地址和端口。然后通过HttpHost构建了服务器的连接信息,并使用RestClient.builder创建了RestHighLevelClient,这是与 Elasticsearch 进行交互的核心客户端对象。

(二)创建索引

import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.create.CreateIndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentType;import java.io.IOException;public class IndexCreator {public static void createMeteorologicalIndex(RestHighLevelClient client) throws IOException {// 创建索引请求对象CreateIndexRequest request = new CreateIndexRequest("meteorological_data_index");// 设置索引的设置,例如分片数量和副本数量request.settings(Settings.builder().put("index.number_of_shards", 3).put("index.number_of_replicas", 1));// 设置索引的映射,即字段类型等信息request.mapping("{\n" +"  \"properties\": {\n" +"    \"temperature\": {\n" +"      \"type\": \"double\"\n" +"    },\n" +"    \"pressure\": {\n" +"      \"type\": \"integer\"\n" +"    },\n" +"    \"humidity\": {\n" +"      \"type\": \"double\"\n" +"    },\n" +"    \"wind_speed\": {\n" +"      \"type\": \"double\"\n" +"    },\n" +"    \"precipitation\": {\n" +"      \"type\": \"double\"\n" +"    },\n" +"    \"observation_time\": {\n" +"      \"type\": \"date\",\n" +"      \"format\": \"yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis\"\n" +"    },\n" +"    \"station_name\": {\n" +"      \"type\": \"keyword\"\n" +"    }\n" +"  }\n" +"}", XContentType.JSON);// 执行创建索引操作CreateIndexResponse response = client.indices().create(request, RequestOptions.DEFAULT);// 检查索引是否创建成功boolean acknowledged = response.isAcknowledged();if (acknowledged) {System.out.println("气象数据索引创建成功");} else {System.out.println("气象数据索引创建失败");}}
}

这段代码首先创建了CreateIndexRequest对象,指定了要创建的索引名称。然后设置了索引的一些基本设置,如分片数和副本数,接着设置了之前设计好的索引映射。最后通过client.indices().create方法执行索引创建操作,并根据返回结果判断索引是否创建成功。

(三)插入气象数据

import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.xcontent.XContentType;import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;public class DataInserter {public static void insertMeteorologicalData(RestHighLevelClient client) throws IOException {// 创建要插入的数据对象Map<String, Object> data = new HashMap<>();data.put("temperature", 25.5);data.put("pressure", 1010);data.put("humidity", 60.0);data.put("wind_speed", 3.5);data.put("precipitation", 0.0);data.put("observation_time", new Date());data.put("station_name", "StationA");// 创建索引请求对象IndexRequest request = new IndexRequest("meteorological_data_index");// 设置文档 ID,如果不设置,Elasticsearch 会自动生成request.id("1");// 设置要插入的数据内容request.source(data, XContentType.JSON);// 执行插入数据操作IndexResponse response = client.index(request, RequestOptions.DEFAULT);// 检查数据是否插入成功if (response.status().getStatus() == 201) {System.out.println("气象数据插入成功");} else {System.out.println("气象数据插入失败");}}
}

这里首先构建了一个Map对象来表示要插入的气象数据,包含了各种气象要素的值以及观测时间和站点名称。然后创建IndexRequest对象,指定索引名称,并设置文档 ID 和数据内容。最后通过client.index方法将数据插入到 Elasticsearch 中,并根据返回状态判断插入是否成功。

(四)查询气象数据

import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;public class DataSearcher {public static List<Map<String, Object>> searchMeteorologicalData(RestHighLevelClient client) throws IOException {// 创建搜索请求对象SearchRequest request = new SearchRequest("meteorological_data_index");// 创建搜索源构建器SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();// 设置查询条件,这里查询所有数据sourceBuilder.query(QueryBuilders.matchAllQuery());request.source(sourceBuilder);// 执行搜索操作SearchResponse response = client.search(request, RequestOptions.DEFAULT);// 处理搜索结果List<Map<String, Object>> resultList = new ArrayList<>();for (SearchHit hit : response.getHits().getHits()) {resultList.add(hit.getSourceAsMap());}return resultList;}
}

上述代码创建了SearchRequest对象用于指定搜索的索引。然后通过SearchSourceBuilder构建搜索条件,这里使用QueryBuilders.matchAllQuery查询所有数据。执行搜索操作后,遍历搜索结果SearchHit对象,将其源数据(即气象数据)添加到List中并返回。

六、单元测试及预期输出

(一)测试连接到 Elasticsearch

import org.elasticsearch.client.RestHighLevelClient;
import org.junit.jupiter.api.Test;import static org.junit.jupiter.api.Assertions.assertNotNull;public class ElasticsearchConnectionTest {@Testpublic void testGetClient() {// 获取 Elasticsearch 客户端RestHighLevelClient client = ElasticsearchConnection.getClient();// 断言客户端不为空assertNotNull(client);}
}

预期输出:测试通过,表明能够成功获取到 Elasticsearch 客户端对象。

(二)测试创建索引

import org.elasticsearch.client.RestHighLevelClient;
import org.junit.jupiter.api.Test;import java.io.IOException;import static org.junit.jupiter.api.Assertions.assertTrue;public class IndexCreatorTest {@Testpublic void testCreateMeteorologicalIndex() throws IOException {// 获取 Elasticsearch 客户端RestHighLevelClient client = ElasticsearchConnection.getClient();// 创建气象数据索引IndexCreator.createMeteorologicalIndex(client);// 这里可以进一步添加代码来验证索引是否真正创建成功,例如检查索引是否存在等操作// 暂时简单地假设创建成功,后续可完善assertTrue(true);}
}

预期输出:如果索引创建成功,测试通过,控制台输出“气象数据索引创建成功”。如果创建失败,控制台输出“气象数据索引创建失败”,并且测试不通过。

(三)测试插入气象数据

import org.elasticsearch.client.RestHighLevelClient;
import org.junit.jupiter.api.Test;import java.io.IOException;import static org.junit.jupiter.api.Assertions.assertTrue;public class DataInserterTest {@Testpublic void testInsertMeteorologicalData() throws IOException {// 获取 Elasticsearch 客户端RestHighLevelClient client = ElasticsearchConnection.getClient();// 插入气象数据DataInserter.insertMeteorologicalData(client);// 这里可以进一步添加代码来验证数据是否真正插入成功,例如根据插入的文档 ID 进行查询验证等操作// 暂时简单地假设插入成功,后续可完善assertTrue(true);}
}

预期输出:如果数据插入成功,测试通过,控制台输出“气象数据插入成功”。如果插入失败,控制台输出“气象数据插入失败”,并且测试不通过。

(四)测试查询气象数据

import org.elasticsearch.client.RestHighLevelClient;
import org.junit.jupiter.api.Test;import java.io.IOException;
import java.util.List;
import java.util.Map;import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;public class DataSearcherTest {@Testpublic void testSearchMeteorologicalData() throws IOException {// 获取 Elasticsearch 客户端RestHighLevelClient client = ElasticsearchConnection.getClient();// 查询气象数据List<Map<String, Object>> resultList = DataSearcher.searchMeteorologicalData(client);// 断言查询结果不为空assertFalse(resultList.isEmpty());}
}

预期输出:如果查询到数据,测试通过,表明能够成功从 Elasticsearch 中查询到气象数据。如果查询结果为空,测试不通过。

七、参考资料文献

  1. Elasticsearch 官方文档:https://www.elasticsearch.org/guide/index.html
  2. Elasticsearch 实战》书籍,作者:[美] 拉法尔·库切拉[波] 马雷克·罗戈津斯基
  3. 相关气象数据处理与存储的学术论文和技术报告。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/11225.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python-leetcode-相同的树

100. 相同的树 - 力扣&#xff08;LeetCode&#xff09; # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left left # self.right right class Solution:de…

IM 即时通讯系统-50-[特殊字符]cim(cross IM) 适用于开发者的分布式即时通讯系统

IM 开源系列 IM 即时通讯系统-41-开源 野火IM 专注于即时通讯实时音视频技术&#xff0c;提供优质可控的IMRTC能力 IM 即时通讯系统-42-基于netty实现的IM服务端,提供客户端jar包,可集成自己的登录系统 IM 即时通讯系统-43-简单的仿QQ聊天安卓APP IM 即时通讯系统-44-仿QQ即…

2025年1月22日(网络编程 udp)

系统信息&#xff1a; ubuntu 16.04LTS Raspberry Pi Zero 2W 系统版本&#xff1a; 2024-10-22-raspios-bullseye-armhf Python 版本&#xff1a;Python 3.9.2 已安装 pip3 支持拍摄 1080p 30 (1092*1080), 720p 60 (1280*720), 60/90 (640*480) 已安装 vim 已安装 git 学习…

基于微信小程序的电子商城购物系统设计与实现(LW+源码+讲解)

专注于大学生项目实战开发,讲解,毕业答疑辅导&#xff0c;欢迎高校老师/同行前辈交流合作✌。 技术范围&#xff1a;SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容&#xff1a;…

MP4分析工具

在实际应用中&#xff0c;我们经常需要对MP4文件进行分析。分析MP4封装格式的工具比较多&#xff0c;下面介绍几款常用的工具&#xff1a; 1、mp4info 优点&#xff1a; 带界面的可视化工具可以清晰看到各个box的组成和层次同时可以分离里面的音视频文件可以看到音视频的时间…

傅里叶分析之掐死教程

https://zhuanlan.zhihu.com/p/19763358 要让读者在不看任何数学公式的情况下理解傅里叶分析。 傅里叶分析 不仅仅是一个数学工具&#xff0c;更是一种可以彻底颠覆一个人以前世界观的思维模式。但不幸的是&#xff0c;傅里叶分析的公式看起来太复杂了&#xff0c;所以很多…

想品客老师的第天:类

类是一个优化js面向对象的工具 类的声明 //1、class User{}console.log(typeof User)//function//2、let Hdclass{}//其实跟1差不多class Stu{show(){}//注意这里不用加逗号&#xff0c;对象才加逗号get(){console.log(后盾人)}}let hdnew Stu()hd.get()//后盾人 类的原理 类…

【Git】初识Git Git基本操作详解

文章目录 学习目标Ⅰ. 初始 Git&#x1f4a5;注意事项 Ⅱ. Git 安装Linux-centos安装Git Ⅲ. Git基本操作一、创建git本地仓库 -- git init二、配置 Git -- git config三、认识工作区、暂存区、版本库① 工作区② 暂存区③ 版本库④ 三者的关系 四、添加、提交更改、查看提交日…

基于单片机的盲人智能水杯系统(论文+源码)

1 总体方案设计 本次基于单片机的盲人智能水杯设计&#xff0c;采用的是DS18B20实现杯中水温的检测&#xff0c;采用HX711及应力片实现杯中水里的检测&#xff0c;采用DS1302实现时钟计时功能&#xff0c;采用TTS语音模块实现语音播报的功能&#xff0c;并结合STC89C52单片机作…

深入解析“legit”的地道用法——从俚语到正式表达:Sam Altman用来形容DeepSeek: legit invigorating(真的令人振奋)

深入解析“legit”的地道用法——从俚语到正式表达 一、引言 在社交媒体、科技圈甚至日常对话中&#xff0c;我们经常会看到或听到“legit”这个词。比如最近 Sam Altman 在 X&#xff08;原 Twitter&#xff09;上发的一条帖子中写道&#xff1a; we will obviously deliver …

微机原理与接口技术期末大作业——4位抢答器仿真

在微机原理与接口技术的学习旅程中&#xff0c;期末大作业成为了检验知识掌握程度与实践能力的关键环节。本次我选择设计并仿真一个 4 位抢答器系统&#xff0c;通过这个项目&#xff0c;深入探索 8086CPU 及其接口技术的实际应用。附完整压缩包下载。 一、系统设计思路 &…

【大模型LLM面试合集】大语言模型架构_MHA_MQA_GQA

MHA_MQA_GQA 1.总结 在 MHA&#xff08;Multi Head Attention&#xff09; 中&#xff0c;每个头有自己单独的 key-value 对&#xff1b;标准的多头注意力机制&#xff0c;h个Query、Key 和 Value 矩阵。在 MQA&#xff08;Multi Query Attention&#xff09; 中只会有一组 k…

【Transformer】手撕Attention

import torch from torch import nn import torch.functional as F import mathX torch.randn(16,64,512) # B,T,Dd_model 512 # 模型的维度 n_head 8 # 注意力头的数量多头注意力机制 class multi_head_attention(nn.Module): def __init__(self, d_model, n_hea…

【Linux】 冯诺依曼体系与计算机系统架构全解

Linux相关知识点可以通过点击以下链接进行学习一起加油&#xff01;初识指令指令进阶权限管理yum包管理与vim编辑器GCC/G编译器make与Makefile自动化构建GDB调试器与Git版本控制工具Linux下进度条 冯诺依曼体系是现代计算机设计的基石&#xff0c;其统一存储和顺序执行理念推动…

冯·诺依曼体系结构

目录 冯诺依曼体系结构推导 内存提高冯诺依曼体系结构效率的方法 你使用QQ和朋友聊天时&#xff0c;整个数据流是怎么流动的&#xff08;不考虑网络情况&#xff09; 与冯诺依曼体系结构相关的一些知识 冯诺依曼体系结构推导 计算机的存在就是为了解决问题&#xff0c;而解…

全面认识了解DeepSeek+利用ollama在本地部署、使用和体验deepseek-r1大模型

文章目录 一、DeepSeek简介二、技术特点三、架构设计3.1、DeepSeek-V33.2、DeepSeek-V23.3、DeepSeek-R1 四、DeepSeek算法4.1、DeepSeek LLM 算法4.2、DeepSeek-V2 算法4.3、DeepSeek-R1 算法4.4、DeepSeek 在算力优化上的算法 五、DeepSeek的使用六、本地部署DeepSeek R1模型…

Python 梯度下降法(七):Summary

文章目录 Python 梯度下降法&#xff08;七&#xff09;&#xff1a;Summary一、核心思想1.1 核心思想1.2 优化方法概述1.3 第三方库的使用 二、 BGD2.1 介绍2.2 torch 库算法2.2 代码示例2.3 SGD2.4 SGD代码示例2.5 MBGD2.6 MBGD 代码示例 三、 Adagrad3.1 介绍3.2 torch 库算…

SpringBoot Web开发(SpringMVC)

SpringBoot Web开发&#xff08;SpringMVC) MVC 核心组件和调用流程 Spring MVC与许多其他Web框架一样&#xff0c;是围绕前端控制器模式设计的&#xff0c;其中中央 Servlet DispatcherServlet 做整体请求处理调度&#xff01; . 除了DispatcherServletSpringMVC还会提供其他…

Web_php_unserialize

代码审计 <?php class Demo { private $file index.php;public function __construct($file) { $this->file $file; }、 //接收一个参数 $file 并赋值给私有属性 $filefunction __destruct() { echo highlight_file($this->file, true); } //在对象销毁时调用&…

Spring Web MVC基础第一篇

目录 1.什么是Spring Web MVC&#xff1f; 2.创建Spring Web MVC项目 3.注解使用 3.1RequestMapping&#xff08;路由映射&#xff09; 3.2一般参数传递 3.3RequestParam&#xff08;参数重命名&#xff09; 3.4RequestBody&#xff08;传递JSON数据&#xff09; 3.5Pa…