倒排索引:当用户输入查询内容,利用分词器对用户输入的内容分词,然后取倒排索引库中匹配,拿到文档id,然后根据文档id查询文档内容(Elasticsearch 默认会返回文档的_source字段(原始 JSON 内容),返回给用户。
1.什么是elasticSearch?*
- elasticsearch是一个开源的分布式搜索引擎,可以用来实现搜索,日志统计,分析,系统分析等功能
**2.什么是elastic stack(ELK)**
- 是以elasticsearch为核心的技术栈,包括beats,Logstash,kibana,elasticsearch
**3.什么是Lucene**
- 是Apache的开源搜索引擎类库,提供了搜索引擎的核心API
Day2
一.索引库操作
text是可拆分的,keyword是不可拆分的,analyzer跟text配合使用,应为只有text需要分词操作,properties只有在对象嵌套的情况下可以用到
创建索引库
索引库的操作
注:索引库和mapping一旦创建无法修改,但是可以添加新的字段
DSL查询语法-match查询
全文检索查询:会对用户输入的内容分词,常用于搜索框搜索
示例:
总结:match和multi_mathc的区别是什么?
- match:根据一个字段查询
- multi_match:根据多个字段查询,参与查询字段越多,查询性能越差
精确查询:精确查询一般是根据id,数值,keyword类型,或者布尔字段来查询
总结:
地理查询:根据经纬度查询
举例:
复合查询:复合查询可以将其他简单查询组合起来,实现更复杂的搜索逻辑
相关性算分:使用match查询时,文档结果会根据与搜索词条的关联度打分,返回结果时按照分值降序排列。
总结:
function score query:使用这个可以修改文档的相关性算分(query score),根据新得到的算分排序
总结:
搜索结果管理-排序
搜索结果管理-分页
搜索结果处理-高亮
数据聚合
聚合的分类
注意:进行聚合操作的的字段不需要做分词,所以改字段不额能使用text类型
总结:![]()
DSL实现Bucket聚合
DSL实现Metrics聚合
RestClient实现聚合
二,数据同步
数据同步的问题分析
elasticsearch中的酒店数据来自于mysql数据库,因此mysql数据发生改变时,elasticsearch也必须跟着改变,这个就是elasticsearch与mysql之间的数据同步。
数据同步的三种方案
方案一:同步调用
方案二:使用MQ异步通知
方案三:监听binglog
总结 :
在项目中使用MQ: 在java中使用RabbitMQ的步骤_银行java项目怎么用到mq-CSDN博客
在 RabbitMQ 中,Exchange(交换机)、Queue(队列) 和 RoutingKey(路由键) 是消息传递的核心组件,它们共同协作决定消息如何从生产者传递到消费者。以下是它们的详细解释和相互关系:
1. Exchange(交换机)
作用
Exchange 是消息的“分发中心”,负责接收生产者发送的消息,并根据规则(绑定关系和路由键)将消息路由到一个或多个队列。
关键特性:
生产者从不直接发送消息到队列,而是发送到 Exchange。
Exchange 的类型决定消息的路由逻辑(如精确匹配、模糊匹配、广播等)。
常见类型
| 类型 | 行为 | 典型场景 |
|---|---|---|
| Direct | 精确匹配RoutingKey,完全一致时路由到队列。 | 订单处理(如order.payment) |
| Fanout | 广播模式,忽略RoutingKey,消息发送到所有绑定的队列。 | 系统通知(全员广播) |
| Topic | 模糊匹配RoutingKey(支持通配符*和#)。 | 日志分级(如error.*) |
| Headers | 不依赖RoutingKey,通过消息头(Headers)的键值对匹配。 | 复杂条件路由(较少使用) |
示例:
// 声明一个Direct类型的Exchange @Bean public DirectExchange orderExchange() { return new DirectExchange("order.exchange"); }2. Queue(队列)
作用
Queue 是消息的“存储容器”,用于暂存消息,等待消费者处理。
关键特性:
消息只有进入队列后,才能被消费者消费。
队列必须绑定到至少一个 Exchange才能接收消息。
队列是独立的,不同队列之间不会共享消息。
重要属性
| 属性 | 说明 |
|---|---|
| Durable | 持久化队列(重启后保留)。 |
| Exclusive | 排他队列(仅限当前连接使用,连接关闭后队列删除)。 |
| Auto-delete | 无消费者时自动删除队列。 |
| Dead Letter | 绑定死信交换机,处理失败消息。 |
示例:
// 声明一个持久化队列 @Bean public Queue orderQueue() { return QueueBuilder.durable("order.queue").build(); }3. RoutingKey(路由键)
作用
RoutingKey 是消息的“路由标签”,由生产者指定,Exchange 根据它和绑定规则决定消息应发送到哪些队列。
关键特性:
在Direct和Topic类型中,RoutingKey 是路由的核心依据。
在Fanout类型中,RoutingKey 会被忽略。
通配符规则(仅Topic类型支持):
*匹配一个单词(如order.*匹配order.payment)。#匹配零或多个单词(如order.#匹配order.payment.success)。
示例:
// 生产者发送消息时指定RoutingKey rabbitTemplate.convertAndSend("order.exchange", "order.payment", message); // Exchange名称 ↑ RoutingKey ↑三者的协作流程
生产者发送消息到 Exchange,并携带
RoutingKey。Exchange根据自身类型和绑定规则,将消息路由到匹配的队列。
绑定规则:队列需通过BindingKey绑定到 Exchange(与RoutingKey匹配)。队列存储消息,等待消费者拉取。
图示:
具体场景示例
场景1:订单支付(Direct Exchange)
Exchange:
order.exchange(类型:Direct)Queue:
payment.queue(绑定键:order.payment)生产者代码:
// 发送支付消息,RoutingKey必须完全匹配"order.payment" rabbitTemplate.convertAndSend("order.exchange", "order.payment", paymentMessage);结果:消息仅进入
payment.queue。
场景2:日志收集(Topic Exchange)
Exchange:
logs.exchange(类型:Topic)Queue:
error.queue(绑定键:*.error)生产者代码:
// 发送错误日志,RoutingKey匹配"*.error" rabbitTemplate.convertAndSend("logs.exchange", "payment.error", errorLog);结果:消息进入
error.queue。
常见问题解答
Q1: Exchange 和 Queue 是多对多关系吗?
是的!一个 Exchange 可以绑定多个 Queue,一个 Queue 也可以绑定到多个 Exchange。
Q2: RoutingKey 和 BindingKey 的区别?
RoutingKey:生产者发送消息时指定的键。
BindingKey:队列绑定到 Exchange 时指定的键(用于匹配 RoutingKey)。
在 Direct 和 Topic 中,两者需匹配;在 Fanout 中两者均被忽略。
Q3: 如何实现消息的延迟投递?
通过 RabbitMQ 插件x-delayed-message或结合死信队列(DLX)实现。
总结
| 组件 | 角色 | 关键点 |
|---|---|---|
| Exchange | 消息路由的“决策者” | 类型(Direct/Fanout/Topic)决定路由逻辑。 |
| Queue | 消息的“存储点” | 消费者从队列获取消息,需绑定到 Exchange。 |
| RoutingKey | 消息的“路由标签” | 在 Direct/Topic 中用于匹配绑定规则,Fanout 中忽略。 |
设计建议:
优先使用Topic实现灵活路由,用Direct确保精确投递。
生产环境务必配置队列持久化和消息确认机制。
ES集群结构
单机的elasticsearch做数据存储,必然面临两个问题:海量的数据问题,单点故障问题。】、
- 海量数据存储问题:将索引库从逻辑上拆分为N个分片(shard),存储到多个节点
- 单点故障问题:将分片数据在不同节点备份
ES集群的节点角色
elasticsearch中集群节点有不同的职责划分:
总结
分布式新增和查询流程
ES集群-故障转移