SpringCloud学习路线(12)——分布式搜索ElasticSeach数据聚合、自动补全、数据同步

news2024/11/25 5:28:12

一、数据聚合

聚合(aggregations): 实现对文档数据的统计、分析、运算。

(一)聚合的常见种类

  • 桶(Bucket)聚合: 用来做文档分组。
    • TermAggregation: 按照文档字段值分组
    • Date Histogram: 按照日期阶梯分组,例如一周一组,一月一组
  • 度量(Metric)聚合: 用以计算一些值,比如最大值、最小值、平均值等。
    • Avg: 求平均值
    • Max: 求最大值
    • Min: 求最小值
    • Stats: 同时求max、min、avg、sum等
  • 管道(pipeline)聚合: 其它聚合的结果为基础的聚合。

参与聚合的字段类型:

  • keyword
  • 数值
  • 日期
  • 布尔

(二)DSL实现聚合

1、桶聚合

当我们统计所有数据中的酒店品牌有几种,此时可以根据酒店品牌的名称做聚合。

(1)基本实现

GET /hotel/_search
{
	"size": 0,	// 设置size为0,结果中不包含文档,只包含聚合结果
	"aggs": {	// 定义聚合
		"brandAgg": {	// 给聚合起个名字
			"terms": {	// 聚合的类型,按照品牌值聚合,所以选择term
				"field": "brand",	//参与聚合的字段
				"size": 20	//	希望获取的聚合结果数量
			}
		}
	}
}

(2)Bucket聚合结果排序

默认情况下,Bucket聚合会统计Bucket内的文档数量,记为_count,并且按照_count降序排序。

那么如何修改排序?

GET /hotel/_search
{
	"size": 0,	// 设置size为0,结果中不包含文档,只包含聚合结果
	"aggs": {	// 定义聚合
		"brandAgg": {	// 给聚合起个名字
			"terms": {	// 聚合的类型,按照品牌值聚合,所以选择term
				"field": "brand",	//参与聚合的字段,
				"order": {	# 排序
					"_count": "asc"
				},
				"size": 20	//	希望获取的聚合结果数量
			}
		}
	}
}

(3)限定聚合范围

默认情况下,Bucket聚合是对索引库的所有文档做聚合,可以限定聚合的文档范围,只要添加query条件。

GET /hotel/_search
{
	"query": {
		"range": {
			"price": {
				"lte": 200	# 只对200元以下的文档聚合
			}
		}
	}
	"size": 0,	// 设置size为0,结果中不包含文档,只包含聚合结果
	"aggs": {	// 定义聚合
		"brandAgg": {	// 给聚合起个名字
			"terms": {	// 聚合的类型,按照品牌值聚合,所以选择term
				"field": "brand",	//参与聚合的字段,
				"order": {	# 排序
					"_count": "asc"
				},
				"size": 20	//	希望获取的聚合结果数量
			}
		}
	}
}

2、Metrics聚合

需求: 要求获取每个品牌的用户评分的min、max、avg等值。

GET /hotel/_search
{
	"size": 0,
	"aggs": {	// 定义聚合
		"brandAgg": {	// 给聚合起个名字
			"terms": {	// 聚合的类型,按照品牌值聚合,所以选择term
				"field": "brand",
				"order": {	# 排序
					"scoreAgg.avg": "desc"
				},
				"size": 20
			},
			"aggs": {	#是brands聚合的子聚合,也就是对分组后对每组分别计算
				"score_stats": {	#聚合名称
					“stats”:	{	#聚合类型,这里的stats可以同时计算min、max、avg等
						"field": "score"	#聚合字段,这里是score
					}
				}
			}
		}
	}
}

(三)RestClient实现聚合

1、桶聚合

//1、创建request对象
SearchRequest request = new SearchRequest("hotel");
//2、DSL组装
request.source().size(0);
request.source().aggregation(
	AggregationBuilders.term("brand_agg").field("brand").size(20)
);

//3、发起请求
SearchResponse response = client.search(request, RequestOptions.DEFAULT);

//4、解析结果
Aggregations aggregations = response.getAggregations();

//5、根据名称获取聚合结果
Terms brandTerms = aggregations.get("brand_agg");

//6、获取桶
List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();

//7、遍历
for (Terms.Bucket bucket : buckets) {
	//获取品牌信息
	String brandName = bucket.getKeyAsString();
}


二、自动补全

(一)拼音分词器

1、离线安装拼音分词器

在这里插入图片描述
2、重启ES即可

(二)自定义分词器

1、直接使用拼音分词器的问题:

  • 拼音分词器不分词,只分拼音
  • 每一个字都形成了拼音
  • 没有汉字

2、分词器的组成

  • character filters: 在tokenizer之前对文本进行处理。例如删除字符、替换字符。
  • tokenizer: 将文本按照一定规则切割词条(term)。例如keyword、ik_smart
  • tokenizer filter: 将tokenizer输出的词条做进一步处理。例如大小写转换、同义词处理、拼音处理。

3、自定义实现结构

在创建索引库时, 通过settings来配置自定义的analyzer(分词器)

PUT /test
{
	"settings": {	#设置配置
		"analysis": {	#解析组
			"analyzer": {	#自定义解析器
				"my_analyzer": {	#分词器名称,按照character 》 tokenizer 》 filter 顺序进行配置
					"tokenizer": "ik_max_word",
					"filter": "pinyin"
				}
			}
		}
	}
}

拓展自定义分词器

PUT /test
{
	"settings": {	#设置配置
		"analysis": {	#解析组
			"analyzer": {	#自定义解析器
				"my_analyzer": {	#分词器名称,按照character 》 tokenizer 》 filter 顺序进行配置
					"tokenizer": "ik_max_word",
					"filter": "py"
				}
			},
			"filter": {	#自定义tokenizer filter
				"py": {	#过滤器名称
					"type": "pinyin",	# 过滤器类型,设置为pinyin
						"keep_full_pinyin": false,	# 是否开启单字拼音
					"keep_joined_full_pinyin": true,	# 是否开启全拼
					"keep_original": true,	# 是否保留中文
					"limit_first_letter_length": 16,
					"remove_duplicated_term": true,
					"none_chinese_pinyin_tokenize": false
				}
			}
		}
	}
}

现在直接使用拼音分词器的问题:

当我们插入两个拼音相同,字义不同的词汇,那么在我们搜索一个同音词汇时,就会出现两者都被搜索出来,显然这是错误的搜索结果。

所以我们需要在创建索引时使用拼音分词器,在搜索索引时使用中文分词器。

"mappings":	{
	"properties": {
		"name": {
			"type": "text",
			"analyzer": "my_analyzer",	# 在索引创建时使用自定义分词器
			"search_analyzer": "ik_smart"	# 在搜索时使用中文分词器
		}
	}
}

(三)自动补全查询

ES 提供 Completion Suggester 查询来实现自动补全功能。
这个查询会匹配以用户输入内容开头的词条并返回。
为了提高补全查询的效率,对于文档中字段的类型有一些约束:

  • 参与补全查询的字段必须是completion类型
  • 字段的内容一般是用来补全多个词条形成的数组
#创建索引库
PUT test
{
	"maapings": {
		"properties": {
			"title": {
				"type": "completion"
			}
		}
	}
}

#	示例数据
POST test/_doc
{
	"title": ["Sony", "WH-1000XM3"]
}
POST test/_doc
{
	"title": ["SK-II", "PITERA"]
}
POST test/_doc
{
	"title": ["Nintendo", "switch"]
}

查询示例

GET /test/_search
{
	"suggest": {
		"title_suggest": {
			"text": "s",	# 关键字
			"completion": {
				"field": "title",	# 补全查询的字段
				"skip_duplicates": true,	# 跳过重复的
				"size": 10	# 获取前10条结果
			}
		}
	}
}

(四)RestClient实现自动补全

//1、准备请求
SearchRequest request = new SearchRequest("hotel");

//2、请求参数
request.source().suggest(new SuggestBuilder().addSuggestion(
	"mySuggestion",	
	SuggestBuilders
		.completionSuggestion("title")
		.prefix("h")
		.skipDuplicates(true)
		.size(10)
));

//3、发送请求
client.search(request, RequestOptions.DEFAULT);

//4、解析结果
Suggest suggest = response.getSuggest();

//5、根据名称获取补全结果
CompletionSuggestion suggestion = suggest.getSuggestion("title_suggest");

//6、获取options并遍历
for (CompletionSuggestion.Entry.Option option : suggestion.getOptions()){
	//获取option的text
	String text = option.getText().string();
}

三、数据同步

ES的数据来自数据库,而数据库数据发生改变时,ES也必须改变,这个就是ES与数据库的数据同步。

在微服务中,负责 数据操作业务 与 数据搜索业务 可能会出现在两个不同的微服务中,数据同步如何实现?

(一)数据同步思路

方式一:同步调用

新增数据 》 数据管理业务(直接写入数据库) 》 调用更新索引库接口 》 数据搜索服务(更新ES)

  • 优点: 实现简单,粗暴
  • 缺点: 数据耦合,业务耦合,性能下降。

方式二:异步通知(现阶段最为推荐的一种方式)

新增数据 》 数据管理业务(直接写入数据库,并给MQ发送消息) 》 MQ(搜索服务订阅) 》 数据搜索服务(更新ES)

  • 优点: 低耦合,实现难度一般
  • 缺点: 依赖mq的可靠性

方式三:监听binlog

新增数据 》 数据管理业务(直接写入mysql数据库,mysql数据库监听binlog库) 》 canal(中间件,通知搜索服务数据变更) 》 数据搜索服务(更新ES)

  • 优点: 完全解除服务间的耦合
  • 缺点: 开启binlog增加数据库负担,实现复杂度高

(二)实现ES与数据库数据同步

我们采用的是异步通知的方式进行数据同步

实现数据同步

  • 声明交换机,queue,RoutingKey
  • 在admin中的增删改业务中完成消息发送
  • 完成消息监听,并更新ES数据

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【计算机网络】2.1——物理层(编码波形、奈氏准则和香农公式计算)

物理层 基本概念 概念 物理层考虑的是怎样才能在连接各种计算机的传输媒体上传输数据比特流 为数据链路层屏蔽了各种传输媒体的差异 数据链路层只需要考虑如何完成本层的协议和服务&#xff0c;而不必考虑网络具体的传输媒体是什么 物理层协议主要任务 机械特性 指明接口所…

区块链学习笔记

区块链技术与应用 数组 列表 二叉树 哈希函数 BTC中的密码学原理 cryptographic hash function collsion resistance(碰撞抵抗) 碰撞指的是找到两个不同的输入值&#xff0c;使得它们的哈希值相同。也就是说&#xff0c;如果存在任意两个输入x和y&#xff0c;满足x ≠ y…

利用Stable diffusion Ai 制作艺术二维码超详细参数和教程

大家有没有发现最近这段时间网上出现了各种各样的AI艺术二维码&#xff0c;这种二维码的出现&#xff0c;简直是对二维码的“颠覆式创新”&#xff0c;直接把传统的二维码提升了一个维度&#xff01;作为设计师的我们怎么可以不会呢&#xff1f; 今天就教大家怎么制作这种超有艺…

Python基于PyTorch实现卷积神经网络回归模型(CNN回归算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 卷积神经网络&#xff0c;简称为卷积网络&#xff0c;与普通神经网络的区别是它的卷积层内的神经元只覆…

使用EasyPoi实现Excel的按模板样式导出

1&#xff0c;横向遍历 #fe 使用#fe命令可以实现集合数据的横向拓展&#xff0c;比如模板代码是 {{#fe:maths t.score}}导出的excel里面就会显示会自当前列&#xff0c;向右拓展&#xff0c;效果可参见下面的导出文件截图 2&#xff0c;横向遍历值 v_fe 使用v_fe命令可以实现…

vue3+ts+elementui-plus二次封装弹框

一、弹框组件BaseDialog <template><div classmain><el-dialog v-model"visible" :title"title" :width"dialogWidth" :before-close"handleClose"><!-- 内容插槽 --><slot></slot><template…

分布式理论:CAP理论 BASE理论

文章目录 1. CAP定理1.1 一致性1.2 可用性1.3 分区容错1.4 矛盾 2. BASE理论3. 解决分布式事务的思路4. 扩展 解决分布式事务问题&#xff0c;需要一些分布式系统的基础知识作为理论指导。 1. CAP定理 Consistency(一致性): 用户访问分布式系统中的任意节点&#xff0c;得到的…

【LeetCode】1143.最长公共子序列(闫氏dp可视化无分析)

class Solution { public:int longestCommonSubsequence(string text1, string text2) {int len1 text1.size(), len2 text2.size();text1 " " text1;text2 " " text2; //以上三行代码需要注意&#xff0c; //第一行是求string长度的方法 //第二行是…

使用3ds Max粒子系统创建飞天箭雨特效场景

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 设置箭头 步骤 1 打开 3ds Max。 打开 3ds Max 步骤 2 我使用多边形建模技术制作了一个简单的箭头&#xff0c;我将 在教程中使用。.max您可以从 下载部分。 箭头.max 步骤 3 将此箭头重命名为静态…

如何安装多个版本的python,python可以装两个版本吗

这篇文章主要介绍了可不可以在同一台计算机上安装多个python版本&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 1、不同版本的python不能安装到同一台计算机上 可以的&#…

绿水青山,水质监测需要智能网关

“ 绿水青山就是金山银山&#xff0c;随着国家在环保领域的持续发力&#xff0c;水作为环境监管极其重要的一极&#xff0c;尤其是河湖水系的监管&#xff0c;也越来越严格&#xff0c;监测布点密度不断加大。水质自动监测站作为河湖断面监测和水质判断比较权威的工具&#xff…

LabVIEW开发谐振器陀螺仪仿真系统

LabVIEW开发谐振器陀螺仪仿真系统 陀螺仪是INS系统中最重要的传感器。它们的性能&#xff08;如精度和偏置稳定性&#xff09;决定了INS系统的水平。陀螺仪按原理分为三类&#xff1a;角动量守恒、萨格纳克效应和科里奥利效应。旋转坐标系中的移动物体受到的力与旋转坐标系的角…

微信小程序 样式和全局配置

WXSS wxss 把屏幕分为750个物理像素&#xff0c;大屏大&#xff0c;小屏小&#xff0c;随着设备不一致自动适配 推荐使用iPhone6作为标准&#xff0c;1个rpx 0.5个px&#xff0c;把px乘以2就是rpx的参数 import 导入外部样式表 import /common/common.wxss 样式 权重一…

Pytorch个人学习记录总结 09

目录 损失函数与反向传播 L1Loss MSELOSS CrossEntropyLoss 损失函数与反向传播 所需的Loss计算函数都在torch.nn的LossFunctions中&#xff0c;官方网址是&#xff1a;torch.nn — PyTorch 2.0 documentation。举例了L1Loss、MSELoss、CrossEntropyLoss。 在这些Loss函数…

Andrew算法求凸包模板

前置知识 向量的叉乘: 设 a ⃗ ( x a , y a , z a ) , b ⃗ ( x b , y b , z b ) \vec a(x_a,y_a,z_a), \vec b(x_b, y_b,z_b) a (xa​,ya​,za​),b (xb​,yb​,zb​), 令 a ⃗ \vec a a 和 b ⃗ \vec b b 的叉乘为 c ⃗ \vec c c , 有: c ⃗ ∣ i j k x a y a z a x b y…

微软对Visual Studio 17.7 Preview 4进行版本更新,新插件管理器亮相

近期微软发布了Visual Studio 17.7 Preview 4版本&#xff0c;而在这个版本当中&#xff0c;全新设计的扩展插件管理器将亮相&#xff0c;并且可以让用户可更简单地安装和管理扩展插件。 据了解&#xff0c;目前用户可以从 Visual Studio Marketplace 下载各式各样的 VS 扩展插…

[DASCTF 2023 0X401七月暑期挑战赛] viphouse复现

这个题想了好久&#xff0c;无果&#xff0c;终于看到WP。照着作了一遍。WP里没有详细解释&#xff0c;所以复现得很辛苦。 程序有5个菜单和1个初始化程序&#xff1a; init 先从os.random读8个字节放到src处login 读入用户名密码&#xff0c;其中密码栈里设的0x40可以读入0x…

【Ap模块EM】08-怎么让Execution Management成为第一个执行的进程?

前面的文章,我们讲述了ubuntu系统上电执行的流程,那么在Ap AutoSAR中Execution Management怎么成为第一个被执行的进程呢额?就是让它取代传统的init进程,成为ubuntu系统第一个执行的进程? 我们可以通过符号链接 symbolic link去实现,这个类似于windows系统中的某个exe文件…

mongoDB详解

mongoDB详解 mongodb是一个nosql数据库&#xff0c;它有高性能、无模式、文档型的特点。他是nosql数据库中功能最丰富&#xff0c;最像关系数据库的。 mongoDb基本介绍 mongodb里面有以下几个核心概念&#xff1a;文档&#xff1a;mongodb数据库的最小数据集&#xff0c;是由…

关于阿里云OSS服务器绑定域名及Https证书

这是一个没有套路的前端博主&#xff0c;热衷各种前端向的骚操作&#xff0c;经常想到哪就写到哪&#xff0c;如果有感兴趣的技术和前端效果可以留言&#xff5e;博主看到后会去代替大家踩坑的&#xff5e; 主页: oliver尹的主页 格言: 跌倒了爬起来就好&#xff5e; 关于阿里云…