ES的使用(Elasticsearch)
ES的使用(Elasticsearch)
es是什么?
es是非关系型数据库,是分布式文档数据库,本质上是一个JSON 文本
为什么要用es?
搜索速度快,近乎是实时的存储、检索数据
怎么使用es?
1.下载es的包(环境要是jdk1.8及以上)(我的资源中有)
2.下载es的可视化界面包(我的资源中有)
3.java编写es的工具类
es与关系型数据库对比
1.下载es的包,解压,运行bat文件(windows)
下载地址:es官网下载地址



elasticsearch.yml配置允许跨域
http.cors.enabled: true
http.cors.allow-origin: "*"

2.下载es的可视化界面包,解压,使用命令npm run start
下载地址:elasticsearch-head-master es可视化工具

打开http:localhost:9100

3.java编写es的工具类
引入es的依赖包
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>6.2.4</version></dependency><dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-client</artifactId><version>6.2.4</version></dependency><dependency><groupId>org.elasticsearch</groupId><artifactId>elasticsearch</artifactId><version>6.2.4</version></dependency>
package com.next.service;import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetRequest;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service;@Service
@Slf4j
public class ESClient implements ApplicationListener<ContextRefreshedEvent> {private final static int CONNECT_TIMEOUT = 100;private final static int SOCKET_TIMEOUT = 60 * 1000;private final static int REQUEST_TIMEOUT = SOCKET_TIMEOUT;private RestHighLevelClient restHighLevelClient; //JDK8及以上private BasicHeader[] basicHeaders;@Overridepublic void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {try {initClient();} catch (Exception e) {log.error("es client init exception", e);try {Thread.sleep(1000);} catch (Exception e1) {}initClient();}}private void initClient() {log.info("es client init start");//请求头时允许的格式basicHeaders = new BasicHeader[]{new BasicHeader("Accept", "application/json;charset=UTF-8")};//es客户端连接设置初始化RestClientBuilder builder = RestClient.builder(new HttpHost("127.0.0.1", 9200, "http"));builder.setDefaultHeaders(basicHeaders)//设置相关超时间配置.setRequestConfigCallback((RequestConfig.Builder configBuilder) -> {configBuilder.setConnectTimeout(CONNECT_TIMEOUT);configBuilder.setSocketTimeout(SOCKET_TIMEOUT);configBuilder.setConnectionRequestTimeout(REQUEST_TIMEOUT);return configBuilder;});restHighLevelClient = new RestHighLevelClient(builder);log.info("es client init end");}//es新增操作public IndexResponse index(IndexRequest indexRequest) throws Exception {try {return restHighLevelClient.index(indexRequest);} catch (Exception e) {log.error("es.index exception,indexRequest:{}", indexRequest, e);throw e;}}//更新操作public UpdateResponse update(UpdateRequest updateRequest) throws Exception {try {return restHighLevelClient.update(updateRequest, basicHeaders);} catch (Exception e) {log.error("es.update exception,updateRequest:{}", updateRequest, e);throw e;}}//查询public GetResponse get(GetRequest getRequest) throws Exception {try {return restHighLevelClient.get(getRequest, basicHeaders);} catch (Exception e) {log.error("es.get exception,updateRequest:{}", getRequest, e);throw e;}}//多个查询请求放在一起查public MultiGetResponse multiGet(MultiGetRequest multiGetRequest) throws Exception {try {return restHighLevelClient.multiGet(multiGetRequest);} catch (Exception e) {log.error("es.multiGet exception,getRequest:{}", multiGetRequest, e);throw e;}}/*** @desc 批量更新*/public BulkResponse bulk(BulkRequest bulkRequest) throws Exception {try {return restHighLevelClient.bulk(bulkRequest,basicHeaders);} catch (Exception e) {log.error("es.multiGet exception,bulkRequest:{}", bulkRequest, e);throw e;}}
}
es启动

4.使用例子:
将车次信息存到es中,方便用户查询(从此地到目的地有哪些车可以乘坐)
package com.next.service;import com.alibaba.google.common.base.Splitter;
import com.alibaba.otter.canal.protocol.CanalEntry;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.next.common.TrainEsConstant;
import com.next.dao.TrainNumberDetailMapper;
import com.next.dao.TrainNumberMapper;
import com.next.model.TrainNumber;
import com.next.model.TrainNumberDetail;
import com.next.util.JsonMapper;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.get.*;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.common.util.set.Sets;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;@Service
@Slf4j
public class TrainNumberService {@Resourceprivate TrainNumberMapper trainNumberMapper;@Resourceprivate TrainCacheService trainCacheService;@Resourceprivate TrainNumberDetailMapper trainNumberDetailMapper;@Resourceprivate ESClient esClient;public void handle(List<CanalEntry.Column> columns, CanalEntry.EventType eventType) throws Exception{if (eventType != CanalEntry.EventType.UPDATE) {log.info("not update,no need care");return;}int trainNumberId = 0;//获取数据库的trainNumberIdfor (CanalEntry.Column column : columns) {if (column.getName().equals("id")) {trainNumberId = Integer.parseInt(column.getValue());break;}}TrainNumber trainNumber = trainNumberMapper.selectByPrimaryKey(trainNumberId);//校验是否有车次if (null == trainNumber) {log.error("not found trainNumber,trainNumberId:{}", trainNumberId);return;}List<TrainNumberDetail> detailList = trainNumberDetailMapper.getByTrainNumberId(trainNumberId);//校验是否有车次详情if (CollectionUtils.isEmpty(detailList)) {log.warn("no detail,no need care,trainNumberId:{}", trainNumber.getName());return;}//将数据写入缓存中trainCacheService.set("TN_" + trainNumber.getName(), JsonMapper.obj2String(detailList));log.info("trainNumber:{} detailList update redis", trainNumber.getName());//将数据存入es中saveES(detailList,trainNumber);log.info("trainNumber:{} detailList update es", trainNumber.getName());}//数据保存到es(客户需要查询的数据放到es--->从此地到目的地有哪些车可以乘坐)private void saveES(List<TrainNumberDetail> detailList, TrainNumber trainNumber) throws Exception{/*** A-B fromStationId- toStationId* 例:北京到大连有多少趟车?* 根据车站的开始结束站,去找车次,即根据fromStationId- toStationId获取到 trainNumberId1,trainNumberId2。。。。* trainNumber: A->B->C* D386:北京->锦州->大连* D387:北京->鞍山->大连** 拆分如下* D386: 北京-锦州 锦州-大连 北京-大连* D387: 北京-鞍山 鞍山-大连 北京-大连*/List<String> list = Lists.newArrayList();int fromStationId = trainNumber.getFromStationId();if (detailList.size() == 1) {//单段int toStationId = trainNumber.getToStationId();list.add(fromStationId + "_" + toStationId);} else {//多段,枚举所有的车次,要保证多段有序for (int i = 0; i < detailList.size(); i++) {//获取开始车站idint tempFromStationId = detailList.get(i).getFromStationId();for (int j = i; j < detailList.size(); j++) {//获取到达车站idint tempToStationId = detailList.get(j).getToStationId();list.add(tempFromStationId+"_"+tempToStationId);}}}//检查数据是否已经存在,存在则不新增,不存在则新增//★如果是for循环里面的话,要封装成批量操作IOMultiGetRequest multiGetRequest = new MultiGetRequest();BulkRequest bulkRequest = new BulkRequest();for(String item:list){multiGetRequest.add(new MultiGetRequest.Item(TrainEsConstant.INDEX,TrainEsConstant.TYPE,item));}//获取处理后的结果MultiGetResponse multiGetItemResponses = esClient.multiGet(multiGetRequest);for(MultiGetItemResponse itemResponse:multiGetItemResponses.getResponses()){if(itemResponse.isFailed()){log.error("multiGet item failed,itemResponse:{}",itemResponse);continue;}GetResponse getResponse = itemResponse.getResponse();if(getResponse == null){log.error("multiGet item is null,itemResponse:{}",itemResponse);continue;}//存储更新es的数据,新增用source传入数据 更新用doc传入数据Map<String,Object> dataMap = Maps.newHashMap();Map<String,Object> map = getResponse.getSourceAsMap();if(!getResponse.isExists() || map == null){//add indexdataMap.put(TrainEsConstant.COLUMN_TRAIN_NUMBER,trainNumber.getName());IndexRequest indexRequest = new IndexRequest(TrainEsConstant.INDEX,TrainEsConstant.TYPE,getResponse.getId()).source(dataMap);bulkRequest.add(indexRequest);continue;}//里面是车次信息 trainNumberId1,trainNumberId2。。。。,需要拆分String origin = (String) map.get(TrainEsConstant.COLUMN_TRAIN_NUMBER);Set<String> set = Sets.newHashSet(Splitter.on(",").trimResults().omitEmptyStrings().split(origin));if(!set.contains(trainNumber.getName())){//update indexdataMap.put(TrainEsConstant.COLUMN_TRAIN_NUMBER,origin+","+trainNumber.getName());UpdateRequest updateRequest = new UpdateRequest(TrainEsConstant.INDEX,TrainEsConstant.TYPE,getResponse.getId()).doc(dataMap);bulkRequest.add(updateRequest);}}//批量更新es的数据(bulkResponse是批量对象转成string打印日志)BulkResponse bulkResponse = esClient.bulk(bulkRequest);log.info("es bulk response:{}",JsonMapper.obj2String(bulkResponse));if(bulkResponse.hasFailures()){throw new RuntimeException("es bulk failure");}}}
车次表
车次明细表

修改数据库中车次表的信息会将数据处理后(出发站-到达站 车次号)存入es

相关文章:
ES的使用(Elasticsearch)
ES的使用(Elasticsearch) es是什么? es是非关系型数据库,是分布式文档数据库,本质上是一个JSON 文本 为什么要用es? 搜索速度快,近乎是实时的存储、检索数据 怎么使用es? 1.下载es的包(环境要…...
车牌识别技术,如何用python识别车牌号
目录 一.前言 二.运行环境 三.代码 四.识别效果 五.参考 一.前言 车牌识别技术(License Plate Recognition, LPR)在交通计算机视觉(Computer Vision, CV)领域具有非常重要的研究意义。以下是该技术的一些扩展说明࿱…...
爬虫工作量由小到大的思维转变---<第二十五章 Scrapy开始很快,越来越慢(追溯篇)>
爬虫工作量由小到大的思维转变---<第二十二章 Scrapy开始很快,越来越慢(诊断篇)>-CSDN博客 爬虫工作量由小到大的思维转变---<第二十三章 Scrapy开始很快,越来越慢(医病篇)>-CSDN博客 前言: 之前提到过,很多scrapy写出来之后,不…...
Servlet入门
目录 1.Servlet介绍 1.1什么是Servlet 1.2Servlet的使用方法 1.3Servlet接口的继承结构 2.Servlet快速入门 2.1创建javaweb项目 2.1.1创建maven工程 2.1.2添加webapp目录 2.2添加依赖 2.3创建servlet实例 2.4配置servlet 2.5设置打包方式 2.6部署web项目 3.servl…...
【C#与Redis】--高级主题--Redis 哨兵
一、简介 1.1 哨兵的概述 哨兵(Sentinel)是 Redis 分布式系统中用于监控和管理多个 Redis 服务器的组件。它的主要目标是确保 Redis 系统的高可用性,通过实时监测主节点和从节点的状态,及时发现并自动处理故障,保证系…...
linux安装python
文章目录 前言一、下载安装包二、安装1.安装依赖2.解压3.安装4.软链接5.验证 总结 前言 本篇文章介绍linux环境下安装python。 一、下载安装包 下载地址:官方网站 我们以最新的标准版为例 二、安装 1.安装依赖 yum -y install openssl-devel ncurses-devel li…...
【如何破坏单例模式(详解)】
✅如何破坏单例模式 💡典型解析✅拓展知识仓✅反射破坏单例✅反序列化破坏单例✅ObjectlnputStream ✅总结✅如何避免单例被破坏✅ 避免反射破坏单例✅ 避免反序列化破坏单例 💡典型解析 单例模式主要是通过把一个类的构造方法私有化,来避免重…...
什么是 SPI,它有什么用?
文章目录 什么是 SPI,它有什么用? 什么是 SPI,它有什么用? SPI 全称是 Service Provider Interface ,它是 JDK 内置的一种动态扩展点的实现。 简单来说,就是我们可以定义一个标准的接口,然后第三…...
FolkMQ 新的消息中间件,v1.0.25
简介 采用 “多路复用” “内存运行” “快照持久化” “Broker 集群模式”(可选)基于 Socket.D 网络应用协议 开发。全新设计,自主架构! 角色功能生产端发布消息(Qos0、Qos1)、发布定时消息ÿ…...
小程序入门-登录+首页
正常新建一个登录页面 创建首页和TatBar,实现登录后底部出现两个按钮 代码 "pages": ["pages/login/index","pages/index/index","pages/logs/logs" ],"tabBar": {"list": [{"pagePath"…...
React快速入门之组件
目录 组件JSX在标签使用{}嵌入JS表达式使用组件组件嵌套以🌲树的方式管理组件间的关系组件纯粹原则 组件 文件:Profile.js export default function Profile({isPacked true,head,stlyeTmp,src,size 80}) {if (isPacked) {head head &q…...
.NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
作者: Jon Galloway - Principal Program Manager, .NET Community Team Mehul Harry - Product Marketing Manager, .NET, Azure Marketing 排版:Alan Wang .NET Conf 2023 是有史以来规模最大的 .NET 会议,来自全球各地的演讲者进行了 100 …...
Hadoop入门学习笔记——六、连接到Hive
视频课程地址:https://www.bilibili.com/video/BV1WY4y197g7 课程资料链接:https://pan.baidu.com/s/15KpnWeKpvExpKmOC8xjmtQ?pwd5ay8 Hadoop入门学习笔记(汇总) 目录 六、连接到Hive6.1. 使用Hive的Shell客户端6.2. 使用Beel…...
【K8S 基本概念】Kurbernetes的架构和核心概念
目录 一、Kurbernetes 1.1 简介 1.2、K8S的特性: 1.3、docker和K8S: 1.4、K8S的作用: 1.5、K8S的特性: 二、K8S集群架构与组件: 三、K8S的核心组件: 一、master组件: 1、kube-apiserve…...
WPS复选框里打对号,显示小太阳或粗黑圆圈的问题解决方法
问题描述 WPS是时下最流行的字处理软件之一,是目前唯一可以和微软office办公套件相抗衡的国产软件。然而,在使用WPS的过程中也会出现一些莫名其妙的错误,如利用WPS打开docx文件时,如果文件包含复选框,经常会出…...
对“企业数据资源相关会计处理暂行规定“的个人理解
附:2023年数据资源入表白皮书下载: 关注WX公众号: commindtech77, 获得数据资产相关白皮书下载地址 1. 回复关键字:数据资源入表白皮书 下载 《2023数据资源入表白皮书》 2. 回复关键字:光大银行 下载 光…...
JavaScript:函数隐含对象arguments/剩余参数. . .c/解构赋值
除了this,在函数内部还存在着一个隐含的参数arguments arguments 是一个类数组对象(伪数组) 调用函数时传递的所有实参,都被存储在arguments中 arguments[0] 表示的是第一个实参 arguments[1] 表示的是第二个实参 以此类推..…...
MFC窗体背景颜色的设置、控件白色背景问题、控件文本显示重叠问题、被父窗体背景覆盖的问题
文章目录 设置mfc窗体背景颜色窗体设置背景颜色后解决控件白色背景解决重复修改控件文本后重叠的问题自绘控件被父窗体背景覆盖的问题 设置mfc窗体背景颜色 设置窗体的背景颜色非常简单,只需要在窗体的OnEraseBkgnd里面填充窗体背景就可以了,甚至直接画…...
c++简易AI
今天小编一时雅兴大发,做了一个c的简易AI,还是很垃圾的! 题外话(每期都会有):我的蛋仔名叫酷影kuying,大家能加我好友吗? 上代码咯! #include<bits/stdc.h> #in…...
java获取两个List集合之间的交集、差集、并集
文章目录 方式一、jdk8 Stream求交集、并集、差集方式二、求交集方式三、collections4.CollectionUtils求交集、差集、并集 本文总结一下java中获取两个List之间的交集、补集、并集的几种方式。 最常用的通过for循环遍历两个集合的方式在这里就不整理了,主要整理一些…...
告别答辩PPT噩梦:百考通AI如何帮你高效搞定毕业答辩
写了大半年的论文,却在最后一步的答辩PPT上栽了跟头?这可能是许多毕业生的真实写照。 01 毕业季的隐形杀手:PPT焦虑症 五月,校园里的玉兰花开得正盛,图书馆的灯光却依然亮到深夜。论文查重通过了,导师点头…...
AI Agent配置文件供应链安全:AgentLint静态分析工具实战指南
1. 项目概述与核心价值最近在折腾AI编程助手,比如Claude Code和Cursor,发现它们的配置文件(.claude/、CLAUDE.md、.cursorrules)功能强大得有点吓人。这些文件不仅能定义代码风格,还能配置“技能”(Skills&…...
如何永久保存微信聊天记录:WeChatMsg完整指南与数据安全终极方案
如何永久保存微信聊天记录:WeChatMsg完整指南与数据安全终极方案 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trendin…...
大语言模型微调实战:从LoRA到QLoRA,一站式开源框架详解
1. 项目概述与核心价值 如果你正在寻找一个能够一站式搞定主流大语言模型微调的开源项目,那么 ssbuild/llm_finetuning 绝对值得你花时间深入研究。这个项目本质上是一个基于 PyTorch 和 Hugging Face Transformers 生态的、高度工程化的微调框架。它最大的魅力在…...
同样遍历 Mat,为什么你的代码慢 10 倍?
文章目录前言一、什么是不连续Mat?1.产生不连续内存的常见场景2.连续与不连续内存本质区别二、常见错误遍历方式&踩坑分析1.错误一:at<>()逐像素访问(速度慢)2.错误二:强行使用一维 data 指针(高危崩溃&…...
从面试旅行到EDA设计:工程思维如何应对混乱与不确定性
1. 一次糟糕的面试旅行:从混乱到反思的工程思维那天早上醒来,看到闹钟指针的那一刻,我就知道一切都乱套了。作为一名在谢菲尔德攻读控制工程学士学位的学生,我本该精神抖擞地前往伦敦郊区参加人生中第一次工业实习面试。然而&…...
英雄联盟R3nzSkin换肤工具:5分钟快速上手免费皮肤解锁指南
英雄联盟R3nzSkin换肤工具:5分钟快速上手免费皮肤解锁指南 【免费下载链接】R3nzSkin-For-China-Server Skin changer for League of Legends (LOL) 项目地址: https://gitcode.com/gh_mirrors/r3/R3nzSkin-For-China-Server 还在为英雄联盟国服昂贵的皮肤价…...
404 Not Found 与 500 Internal Server Error 全方位解析
前言在日常开发与运维中,HTTP 状态码是我们最常打交道的一类信号。其中,404 与 500 两类错误几乎占据了线上问题的一半以上。你是否遇到过:用户反馈页面打不开,浏览器提示 404 Not Found,但实际上资源明明存在…...
图解人工智能(12)自动做化学实验的机器
近年来,人工智能和传统科学的结合备受瞩目。2019年,英国利物浦大学在《自然》杂志发表论文,介绍了一种可以自动做化学实验的机器人。查找相关资料,并讨论一下类似的工作能给人类社会带来怎样的变革。首先,实验人员的培…...
YOLO26改进 | MSHC多尺度异构卷积:用方形核与条带核捕获复杂空间纹理,以清晰动机打造超强创新!
# YOLO26改进最新创新改进系列 | MSHC多尺度异构卷积:用方形核与条带核捕获复杂空间纹理,以清晰动机打造超强创新! 购买相关资料后畅享一对一答疑! 畅享超多免费持续更新且可大幅度提升文章档次的纯干货工具! 这篇采用…...

