【ElasticSearch】ElasticSearch实战
初步检索
检索 ES 信息
1)、GET /_cat/nodes
:查看所有节点
127.0.0.1 44 83 1 0.01 0.01 0.00 dilm * 1b06a843b8e3
*代表主节点
2)、GET /_cat/health
:查看健康状况
1718265331 07:55:31 elasticsearch yellow 1 1 4 4 0 0 1 0 - 80.0%
green表示健康值正常
3)、GET /_cat/master
:查看主节点
7NZD92ZKTTGcvCiRiYgipw 127.0.0.1 127.0.0.1 1b06a843b8e3
4)、GET /_cat/indices
:查看所有索引 ,等价于mysql数据库的show databases;
green open .kibana_task_manager_1 sDt5UmEmSHqFXBxT7O80KQ 1 0 2 0 21.7kb 21.7kb green open .apm-agent-configuration iQ8r6SPhRkm2Cq86D2koWg 1 0 0 0 283b 283b yellow open index ilDKtPGtQDOSagS6tk9QPw 1 1 1 0 3.4kb 3.4kb green open .kibana_1 9vfcQSsNSWGunawX2uhkqQ 1 0 8 0 32.7kb 32.7kb
新增文档
保存一个数据,保存在哪个索引的哪个类型下(哪张数据库哪张表下),保存时用唯一标识指定
# 在customer索引下的external类型下保存1号数据 PUT customer/external/1 {"name":"John Doe" }
#! Deprecation: [types removal] Specifying types in document index requests is deprecated, use the typeless endpoints instead (/{index}/_doc/{id}, /{index}/_doc, or /{index}/_create/{id}). {"_index" : "customer", // 表明该数据在哪个数据库下"_type" : "external", // 表明该数据在哪个类型下"_id" : "1", // 表明被保存数据的id"_version" : 1, // 被保存数据的版本"result" : "created", // 表示创建了一条数据"_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 0,"_primary_term" : 1 }
PUT 和 POST 的区别
-
POST如果不指定id,会自动生成id;指定id就会修改这个数据,并新增版本号
-
PUT必须指定id,一般用来做修改操作,不指定id会报错
查看文档
GET /customer/external/1
:查看customer索引下的external类型下的文档
{"_index" : "customer","_type" : "external","_id" : "1","_version" : 1,"_seq_no" : 0, // 并发控制字段,每次更新都会+1,用来做乐观锁"_primary_term" : 1, // 同上,主分片重新分配,如重启,就会变化"found" : true,"_source" : {"name" : "John Doe"} }
更新文档
POST customer/externel/1/_update {"doc":{"name":"John Smith"} } 或者 POST customer/externel/1 {"doc":{"name":"John Smith"} } 或者 PUT customer/externel/1 {"doc":{"name":"John Smith"} }
带有_update的情况下,POST操作会对比原文档数据,如果相同不做操作;PUT操作总会重新保存并增加version版本
删除文档或索引
ES并没有提供删除类型的操作,只提供了删除索引和文档的操作
DELETE customer/external/1 DELETE customer
{"_index": "customer","_type": "external","_id": "1","_version": 14,"result": "deleted","_shards": {"total": 2,"successful": 1,"failed": 0},"_seq_no": 22,"_primary_term": 6 }
批量操作_bulk
bulk api按顺序执行所有的action(动作)。如果一个单个的动作因任何原因失败,它将 继续处理 它后面剩余的动作。当bulk api返回时,它将提供每个动作的状态(与发送的顺序相同),所以您可以检查是否一个指定的动作是否失败了
# 对整个索引执行批量操作 POST /_bulk {"delete":{"_index":"website","_type":"blog","_id":"123"}} {"create":{"_index":"website","_type":"blog","_id":"123"}} {"title":"my first blog post"} {"index":{"_index":"website","_type":"blog"}} {"title":"my second blog post"} {"update":{"_index":"website","_type":"blog","_id":"123"}} {"doc":{"title":"my updated blog post"}}
{"took" : 227,"errors" : false,"items" : [{"delete" : {"_index" : "website","_type" : "blog","_id" : "123","_version" : 1,"result" : "not_found", // 1、没有该记录"_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 0,"_primary_term" : 1,"status" : 404}},{"create" : {"_index" : "website","_type" : "blog","_id" : "123","_version" : 2,"result" : "created", // 2、创建成功"_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 1,"_primary_term" : 1,"status" : 201}},{"index" : {"_index" : "website","_type" : "blog","_id" : "rDm8EJABRl6keg4IGZWd","_version" : 1,"result" : "created", // 3、保存成功"_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 2,"_primary_term" : 1,"status" : 201}},{"update" : {"_index" : "website","_type" : "blog","_id" : "123","_version" : 3,"result" : "updated", // 4、更新成功"_shards" : {"total" : 2,"successful" : 1,"failed" : 0},"_seq_no" : 3,"_primary_term" : 1,"status" : 200}}] }
进阶检索
_search检索
_search检索支持两种方式:参数拼uri和参数放在请求体
# 请求参数方式检索 GET bank/_search?q=*&sort=account_number:asc 说明: q=* # 查询所有 sort # 排序字段 asc # 升序 # 请求参数放在请求体 GET /bank/_search {"query": { "match_all": {} },"sort": [{ "account_number": "asc" },{ "balance":"desc"}] }
返回内容:
-
took
– 花费多少ms搜索 -
timed_out
– 是否超时 -
_shards
– 多少分片被搜索了,以及多少成功/失败的搜索分片 -
max_score
–文档相关性最高得分 -
hits.total.value
- 多少匹配文档被找到 -
hits.sort
- 结果的排序key(列),没有的话按照score排序 -
hits._score
- 相关得分 (not applicable when usingmatch_all
)
DSL
ES提供了一个可以执行查询的Json风格的DSL(domain-specific language,领域特定语言),被称为Query DSL,该查询语言非常全面
如果针对于某个字段,那么它的结构如下: {QUERY_NAME: { # 使用的功能FIELD_NAME: { # 功能参数ARGUMENT: VALUE,ARGUMENT: VALUE,...} } }
示例 ,使用时不要加#注释内容
GET bank/_search {"query": { # 查询的字段"match_all": {}},"from": 0, # 从第几条文档开始查"size": 5,"_source":["balance"],"sort": [{"account_number": { # 返回结果按哪个列排序"order": "desc" # 降序}}] } _source为要返回的字段
query定义如何查询;
-
match_all查询类型【代表查询所有的索引】,es中可以在query中组合非常多的查询类型完成复杂查询;
-
from+size限定,完成分页功能;
-
sort排序,多字段排序,会在前序字段相等时后续字段内部排序,否则以前序为准;
Mapping映射
Mapping 是用来定义一个文档(document),以及它所包含的属性(field)是如何存储和索引的。使用maping来定义:
-
哪些字符串属性应该被看做全文本属性(full text fields);
-
哪些属性包含数字,日期或地理位置;
-
文档中的所有属性是否都嫩被索引(all 配置);
-
日期的格式;
-
自定义映射规则来执行动态添加属性;
-
查看mapping信息:GET bank/_mapping
创建索引并指定映射
第一次存储数据的时候es就猜出了映射 第一次存储数据前可以指定映射
PUT /my_index {"mappings": {"properties": {"age": {"type": "integer"},"email": {"type": "keyword" # 指定为keyword},"name": {"type": "text" # 全文检索。保存时候分词,检索时候进行分词匹配}}} }
查看映射
GET /my_index
{"my_index" : {"aliases" : { },"mappings" : {"properties" : {"age" : {"type" : "integer"},"email" : {"type" : "keyword"},"name" : {"type" : "text"}}},"settings" : {"index" : {"creation_date" : "1718270515822","number_of_shards" : "1","number_of_replicas" : "1","uuid" : "OfDvFnDvQiq8Jq-3oDHDog","version" : {"created" : "7040299"},"provided_name" : "my_index"}}} }
添加字段映射
PUT /my_index/_mapping {"properties": {"employee-id": {"type": "keyword","index": false # 字段不能被检索,只是一个冗余字段}} }
不能更新映射
对于已经存在的字段映射,我们不能更新。更新必须创建新的索引,进行数据迁移
数据迁移
先创建new_twitter的正确映射,然后使用如下方式进行数据迁移
6.0以后写法 POST reindex {"source":{"index":"twitter"},"dest":{"index":"new_twitters"} } 老版本写法 POST reindex {"source":{"index":"twitter","twitter":"twitter"},"dest":{"index":"new_twitters"} }
更多详情见: Reindex API | Elasticsearch Guide [7.6] | Elastic
分词
内置的分词只支持对英文的分词,安装 ik 分词器
SpringBoot 整合 ES
客户端选型
-
通过 9300 端口(ES 集群间通信也是 9300 端口), 维护一个 TCP 长连接
spring 提供了 spring-data-elasticsearch:transport-api.jar
-
springboot版本不同,transport-api.jar 不同,不能适配 ES 版本
-
7.x 已经不建议使用,8 以后就要废弃
-
-
通过 9200 端口,给 ES 发送 HTTP 请求
-
JestClient:非官方,更新慢
-
RestTemplate:ES 很多操作需要自己封装,麻烦
-
HttpClient:同上
-
Elasticsearch-Rest-Client:官方 RestClient,封装了 ES 操作,API 层次分明,上手简单
最终选择 Elasticsearch-Rest-Client(elasticsearch-rest-high-level-client),参考文档:Java High Level REST Client | Java REST Client [7.17] | Elastic
ES 做商品检索
商品上架需求
-
上架的商品才可以在网站展示
-
上架的商品可以被检索
商品如何检索
ES 比 MySQL 更适合做全文检索,它的数据存在内存中,对于电商中海量商品的搜索场景, 可以通过 ES 数据分片的集群部署方式,提供全文检索和复杂查询支持
对于搜索场景,我们要支持品牌、类型、属性规格的搜索
SKU 在 ES 中怎么存
分析:商品上架在 ES 中是存 SKU 还是 SPU?
-
检索的时候输入名字,是需要按照sku的title进行全文检索的
-
检素使用商品规格,规格是spu的公共属性,每个spu是一样的
-
按照分类id进去的都是直接列出spu的,还可以切换
-
我们如果将sku的全量信息保存到es中(包括spu属性〕就太多字段了
方案1
{skuId:1spuId:11skyTitile:华为xxprice:999saleCount:99attr:[{尺寸:5},{CPU:高通945},{分辨率:全高清}] } 在sku级别冗余存储规格属性 缺点:如果每个sku都存储规格参数(如尺寸),会有冗余存储,因为每个spu对应的sku的规格参数都一样 假设100万商品,每个spu平均规格属性有2kb数据,等于冗余存储多用了2个G的内存
方案2
sku索引 {spuId:1skuId:11 } attr索引 {spuId:11attr:[{尺寸:5},{CPU:高通945},{分辨率:全高清}] } 不冗余存储,规格属性只在spu级别保存了一份 缺点:因为展示的规格属性是动态计算出来的,如何计算?在我们搜索商品关键字时,ES 会搜索出所有标题里包含这个关键字的商品,聚合起来分析这些商品涉及的所有规格属性和属性值。如果在这种方案下实现动态计算,假设搜索“小米”有10w个商品,对应4000个spu,再根据4000个spu查询对应的规格属性 假设spuId用long类型,占8字节,一个请求占8B*4000=32000B=32KB 假设有1w人并发检索,就传了320MB的数据,占用大量网络带宽,很可能会网络阻塞
最终选择方案1,用空间换时间
建立索引
-
{ "type": "keyword" },保持数据精度问题,可以检索,但不分词
-
"analyzer": "ik_smart",中文分词器
-
"index": false,不可被检索,不生成index
-
"doc_values": false ,默认为true,不可被聚合,es就不会维护一些聚合的信息
PUT product {"mappings":{"properties": {"skuId":{ "type": "long" },"spuId":{ "type": "keyword" }, # 不可分词"skuTitle": {"type": "text","analyzer": "ik_smart" # 中文分词器},"skuPrice": { "type": "keyword" }, # 保证精度问题"skuImg" : { "type": "keyword" }, # 视频中有false"saleCount":{ "type":"long" },"hasStock": { "type": "boolean" }, # 只存是否有库存,不存库存量"hotScore": { "type": "long" }, # 热度评分"brandId": { "type": "long" },"catalogId": { "type": "long" },"brandName": {"type": "keyword"}, # 视频中有false"brandImg":{"type": "keyword","index": false, # 不可被检索,不生成index,只用做页面使用"doc_values": false # 不可被聚合,默认为true},"catalogName": {"type": "keyword" }, # 视频里有false"attrs": {"type": "nested", # 嵌入式对象,避免被扁平化处理"properties": {"attrId": {"type": "long" },"attrName": {"type": "keyword","index": false, # 不可被索引,不生成索引"doc_values": false},"attrValue": {"type": "keyword" }}}}} }
nested 嵌入式对象
数组类型的对象会被扁平化处理(对象的每个属性会分别存储到一起)
user.name=["aaa","bbb"] user.addr=["ccc","ddd"] 这种存储方式,可能会发生如下错误: 错误检索到{aaa,ddd},这个组合是不存在的
数组的扁平化处理会使检索能检索到本身不存在的,为了解决这个问题,就采用了嵌入式属性,数组里是对象时用嵌入式属性(不是对象无需用嵌入式属性)
nested阅读:ElasticSearch - 嵌套对象 nested_elasticsearch nested java-CSDN博客
使用聚合:Elastic search中使用nested类型的内嵌对象-CSDN博客
相关文章:
【ElasticSearch】ElasticSearch实战
初步检索 检索 ES 信息 1)、GET /_cat/nodes:查看所有节点 127.0.0.1 44 83 1 0.01 0.01 0.00 dilm * 1b06a843b8e3 *代表主节点 2)、GET /_cat/health:查看健康状况 1718265331 07:55:31 elasticsearch yellow 1 1 4 4 0 0…...
48-3 内网渗透 - 令牌操纵
访问令牌操纵 Windows 操作系统的访问控制模型是其安全性的重要组成部分,主要由访问令牌(Access Token)和安全描述符(Security Descriptor)构成。访问令牌是访问者持有的,而安全描述符则由被访问对象持有。通过对比访问令牌和安全描述符的内容,Windows 可以判断访问者是…...
架构师之 Kafka 核心概念入门
Kafka 核心概念 作为架构师,理解 Kafka 的核心概念至关重要。这些概念是构建高效、可靠的 Kafka 系统的基础。 以下是需要掌握的 Kafka 核心概念及其详细说明: 1. Topic 定义:Topic 是 Kafka 中用于存储和分类消息的逻辑命名空间。每个 Topic 代表一类数据流, 例如日志、…...

Redis通用命令详解
文章目录 一、Redis概述1.1 KEYS:查看符合模板的所有 key1.2 DEL:删除一个指定的 key1.3 EXISTS:判断 key 是否存在1.4 EXPIRE:给一个 key 设置有效期,有效期到期时该 key 会被自动删除1.5 TTL:查看一个 ke…...

物联网设备安装相关知识整理
拓扑图 对于ADAM-4150先接设备的整体的供电。 ADAM-4150就涉及到几个电子元器件的连接,一个是485-232的转换器,一个是将RS-232转换为USB的转接口,因为现在的计算机很多都去掉了RS-232接口而使用USB接口。 4150右侧有个拨码,分别两…...

React实现H5手势密码
监测应用进入前后台 在JavaScript中,监听H5页面是否在前台或后台运行,主要依赖于Page Visibility API。这个API在大多数现代浏览器中都是支持的,包括苹果的Safari和谷歌的Chrome(也就基本覆盖了Android和iOS平台)。下…...

[leetcode hot 150]第十五题,三数之和
题目: 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复…...

视频AI分析定时任务思路解析
序言: 最近项目中用到视频ai分析,由于sdk涉及保密,不便透露,仅对定时任务分析的思路作出分享,仅供参考。 1、定时任务 由于ai服务器的性能上限,只能同时对64个rtsp流分析一种算法,或者对8个rts…...
tcp 粘包和拆包 及 解决粘包方案
什么是粘包和拆包 .TCP 是面向连接的,面向流的,提供高可靠性服务。收发两端(客户端和服务器端)都要有一一成对的 socket,因此,发送端为了将多个发给接收端的包,更有效的发给对方,使…...

【2024泰迪杯】B 题:基于多模态特征融合的图像文本检索20页论文及Python代码
【2024泰迪杯】B 题:基于多模态特征融合的图像文本检索20页论文及Python代码 相关链接 【2024泰迪杯】A 题:生产线的故障自动识别与人员配置 Python代码实现 【2024泰迪杯】B 题:基于多模态特征融合的图像文本检索Python代码实现 【2024泰迪…...

华为设备telnet 远程访问配置实验简述
一、实验需求: 1、AR1模拟电脑telnet 访问AR2路由器。 二、实验步骤: 1、AR1和AR2接口配置IP,实现链路通信。 2、AR2配置AAA模式 配置用户及密码 配置用户访问级别 配置用户telnet 访问服务 AR2配置远程服务数量 配置用户远程访问模式为AAA 配置允许登录…...
在HTML中,如何正确使用语义化标签?
在HTML中,使用语义化标签可以使得网页结构更加清晰和易于理解。以下是一些正确使用语义化标签的方法: 使用合适的标题标签(h1-h6)来标识网页的标题,以及页面中的各个区块的标题。 <h1>网页标题</h1> <…...
WHAT - 高性能和内存安全的 Rust(一)
目录 一、介绍1.1 示例代码1.2 关键特性内存安全零成本抽象:高效性能示例代码:使用迭代器的零成本抽象示例代码:泛型和单态化总结 并发编程:防止数据竞争Rust 并发编程示例Rust 的所有权系统防止数据竞争总结 丰富的类型系统包管理…...
八、C#运算符
C#运算符 晕杜甫是一种告诉编辑器执行特定的数学或逻辑操作的符号。C#有丰富的内置运算符,分类如下: 算术运算符关系运算符逻辑运算符位运算符赋值运算符其他运算符 算术运算符 下表显示了 C# 支持的所有算术运算符。假设变量 A 的值为 10,…...
【HiveSQL】join关联on和where的区别及效率对比
测试环境:hive on spark spark版本:3.3.1 一、执行时机二、对结果集的影响三、效率对比1.内连接1)on2)where 2.外连接1)on2)where 四、总结PS 一、执行时机 sql连接中,where属于过滤条件&#…...

如何解决windows自动更新,释放C盘更新内存
第一步:首先关闭windows自动更新组件 没有更新windows需求,为了防止windows自动更新,挤占C盘空间,所以我们要采取停止Windows Update服务。按下WinR打开运行对话框,输入services.msc, 然后按Enter。在服务…...

初学51单片机之PWM实例呼吸灯以及遇到的问题(已解答)
PWM全名Pulse Width Modulation中文称呼脉冲宽度调制 如图 这是一个周期10ms、频率是100HZ的波形,但是每个周期内,高低电平宽度各不相同,这就是PWM的本质。 占空比是指高电平占整个周期的比列,上图第一个波形的占空比是40%,第二个…...

手机天线都去哪里了?
在手机的演变历程中,天线的设计和位置一直是工程师们不断探索和创新的领域。你是否好奇,现在的手机为什么看不到那些曾经显眼的天线了呢? 让我们一起揭开这个谜题。 首先,让我们从基础开始:手机是如何发出电磁波的&…...

计算机网络 —— 应用层(电子邮件)
计算机网络 —— 应用层(电子邮件) 电子邮件发送电子邮件的过程SMTP特性工作流程 电子邮件格式MIME关键组件工作方式 POP/IMAPPOP(邮局协议)IMAP(因特网邮件访问协议) 基于万维网的电子邮箱特点优势常见的基…...
Java18新特性(极简)
一、引言 自1995年Java语言首次亮相以来,它已经成为企业级应用、移动应用和游戏开发等领域不可或缺的一部分。随着技术的不断进步,Java也在持续演化,每个新版本都带来了诸多新特性和性能优化,旨在提升开发者的编程效率和应用程序的…...

Keil 中设置 STM32 Flash 和 RAM 地址详解
文章目录 Keil 中设置 STM32 Flash 和 RAM 地址详解一、Flash 和 RAM 配置界面(Target 选项卡)1. IROM1(用于配置 Flash)2. IRAM1(用于配置 RAM)二、链接器设置界面(Linker 选项卡)1. 勾选“Use Memory Layout from Target Dialog”2. 查看链接器参数(如果没有勾选上面…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Java + Spring Boot + Mybatis 实现批量插入
在 Java 中使用 Spring Boot 和 MyBatis 实现批量插入可以通过以下步骤完成。这里提供两种常用方法:使用 MyBatis 的 <foreach> 标签和批处理模式(ExecutorType.BATCH)。 方法一:使用 XML 的 <foreach> 标签ÿ…...

人机融合智能 | “人智交互”跨学科新领域
本文系统地提出基于“以人为中心AI(HCAI)”理念的人-人工智能交互(人智交互)这一跨学科新领域及框架,定义人智交互领域的理念、基本理论和关键问题、方法、开发流程和参与团队等,阐述提出人智交互新领域的意义。然后,提出人智交互研究的三种新范式取向以及它们的意义。最后,总结…...
华为OD最新机试真题-数组组成的最小数字-OD统一考试(B卷)
题目描述 给定一个整型数组,请从该数组中选择3个元素 组成最小数字并输出 (如果数组长度小于3,则选择数组中所有元素来组成最小数字)。 输入描述 行用半角逗号分割的字符串记录的整型数组,0<数组长度<= 100,0<整数的取值范围<= 10000。 输出描述 由3个元素组成…...

高考志愿填报管理系统---开发介绍
高考志愿填报管理系统是一款专为教育机构、学校和教师设计的学生信息管理和志愿填报辅助平台。系统基于Django框架开发,采用现代化的Web技术,为教育工作者提供高效、安全、便捷的学生管理解决方案。 ## 📋 系统概述 ### 🎯 系统定…...

Matlab实现任意伪彩色图像可视化显示
Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中,如何展示好看的实验结果图像非常重要!!! 1、灰度原始图像 灰度图像每个像素点只有一个数值,代表该点的亮度(或…...

高抗扰度汽车光耦合器的特性
晶台光电推出的125℃光耦合器系列产品(包括KL357NU、KL3H7U和KL817U),专为高温环境下的汽车应用设计,具备以下核心优势和技术特点: 一、技术特性分析 高温稳定性 采用先进的LED技术和优化的IC设计,确保在…...

Copilot for Xcode (iOS的 AI辅助编程)
Copilot for Xcode 简介Copilot下载与安装 体验环境要求下载最新的安装包安装登录系统权限设置 AI辅助编程生成注释代码补全简单需求代码生成辅助编程行间代码生成注释联想 代码生成 总结 简介 尝试使用了Copilot,它能根据上下文补全代码,快速生成常用…...