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

这篇具有很好参考价值的文章主要介绍了SpringCloud学习路线(12)——分布式搜索ElasticSeach数据聚合、自动补全、数据同步。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、数据聚合

聚合(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、离线安装拼音分词器

SpringCloud学习路线(12)——分布式搜索ElasticSeach数据聚合、自动补全、数据同步,spring cloud,学习,分布式
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与数据库数据同步

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

实现数据同步文章来源地址https://www.toymoban.com/news/detail-609728.html

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

到了这里,关于SpringCloud学习路线(12)——分布式搜索ElasticSeach数据聚合、自动补全、数据同步的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • SpringCloud系列(十六)[分布式搜索引擎篇] - DSL 查询及相关性算分的学习 (部分)

    SpringCloud系列(十六)[分布式搜索引擎篇] - DSL 查询及相关性算分的学习 (部分)

    在SpringCloud系列(十五)[分布式搜索引擎篇] - 结合实际应用场景学习并使用 RestClient 客户端 API这篇文章中我们已经对 RestClient 有了初步的了解, 并且已经将一些数据进行了存储, 但是这并不是我们学习 ElasticSearch 的目的, ElasticSearch 最擅长的还是对数据的搜索及分析, 因此本篇

    2024年02月17日
    浏览(17)
  • 【Springcloud】分布式搜索elasticsearch

    【Springcloud】分布式搜索elasticsearch

    先看下翻译: elasticsearch是一款非常强大的 开源搜索引擎 ,可以帮助我们 从海量数据中快速找到需要的内容 以下是生活中ES的使用场景: 项目在运行的时候会产生海量的日志信息,而elasticsearch结合kibana、Logstash、Beats,也就是elastic stack( ELK ),即ELK技术栈。被广泛应用在

    2024年02月08日
    浏览(13)
  • 微服务技术栈SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式(五):分布式搜索 ES-下

    微服务技术栈SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式(五):分布式搜索 ES-下

    聚合(aggregations)可以实现对文档数据的统计、分析、运算。聚合常见的有三类: 桶(Bucket)聚合:用来对文档做分组 TermAggregation:按照文档字段值分组 Date Histogram:按照日期阶梯分组,例如一周为一组,或者一月为一组 度量(Metric)聚合:用以计算一些值,比如:最大值

    2024年03月26日
    浏览(10)
  • Springcloud中间件-----分布式搜索引擎 Elasticsearch

    Springcloud中间件-----分布式搜索引擎 Elasticsearch

    该笔记是根据黑马程序员的课来自己写了一遍的,b站有对应教程和资料 第一部分 第二部分 第三部分 预计看完跟着练习5小时足够 1.1.1.elasticsearch的作用 elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容 例如:

    2024年02月08日
    浏览(39)
  • SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈

    SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式,系统详解springcloud微服务技术栈

    我们发现在微服务中有一个令人头疼的问题——部署,用Docker去解决这个部署难题 1、项目部署的问题 2、Docker 扔到一台机器上,它们的依赖难道没有干扰吗?不会,docker将打包好的程序放到一个隔离容器去运行,使用沙箱机制,避免互相干扰,之间不可见,这样就解决了混

    2023年04月24日
    浏览(9)
  • (黑马出品_07)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

    (黑马出品_07)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

    [此文档是在心向阳光的天域的博客加了一些有助于自己的知识体系,也欢迎大家关注这个大佬的博客](https://blog.csdn.net/sinat_38316216/category_12263516.html) [是这个视频](https://www.bilibili.com/video/BV1LQ4y127n4/?p=5spm_id_from=pageDrivervd_source=9beb0a2f0cec6f01c2433a881b54152c) 聚合 可以让我们极其方便

    2024年03月12日
    浏览(8)
  • (黑马出品_高级篇_04)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

    (黑马出品_高级篇_04)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式

    [此文档是在心向阳光的天域的博客加了一些有助于自己的知识体系,也欢迎大家关注这个大佬的博客](https://blog.csdn.net/sinat_38316216/category_12263516.html) [是这个视频](https://www.bilibili.com/video/BV1LQ4y127n4/?p=5spm_id_from=pageDrivervd_source=9beb0a2f0cec6f01c2433a881b54152c) 消息队列在使用过程中,面

    2024年03月19日
    浏览(12)
  • Redis学习路线(6)—— Redis的分布式锁

    Redis学习路线(6)—— Redis的分布式锁

    一、分布式锁的模型 (一)悲观锁: 认为线程安全问题一定会发生,因此在操作数据之前先获取锁,确保线程串行执行。例如Synchronized、Lock都属于悲观锁。 优点: 简单粗暴 缺点: 性能略低 (二)乐观锁: 认为线程安全问题不一定会发生,因此不加锁,只有在更新数据时

    2024年02月14日
    浏览(10)
  • SpringCloud分布式搜索引擎、数据聚合、ES和MQ的结合使用、ES集群的问题

    SpringCloud分布式搜索引擎、数据聚合、ES和MQ的结合使用、ES集群的问题

    目录 数据聚合 聚合的分类 ​编辑 DSL实现Bucket聚合 ​编辑  DSL实现Metrics聚合​编辑 RestAPI实现聚合  对接前端接口​编辑  自定义分词器​编辑 Completion suggester查询 Completion suggester查询 酒店数据自动补全 实现酒店搜索框界面输入框的自动补全  数据同步问题分析​编辑 同

    2024年02月16日
    浏览(26)
  • 微服务学习——分布式搜索

    微服务学习——分布式搜索

    elasticsearch是一款非常强大的开源搜索引擎,可以帮助我们从海量数据中快速找到需要的内容。 elasticsearch结合kibana、Logstash、Beats,也就是elastic stack(ELK)。被广泛应用在日志数据分析、实时监控等领域。 elasticsearch是elastic stack的核心,负责存储、搜索、分析数据。 Lucene是一个

    2024年02月03日
    浏览(8)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包