【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【11】ElasticSearch

news2024/12/23 1:57:41

持续学习&持续更新中…

守破离


【雷丰阳-谷粒商城 】【分布式高级篇-微服务架构篇】【11】ElasticSearch

  • 简介
  • 基本概念
  • ElasticSearch概念-倒排索引
  • 安装
  • 基本命令
  • ik 分词器
  • SpringBoot整合
    • 测试存储数据:
    • 测试复杂检索
    • 同步与异步调用
  • 参考

在这里插入图片描述

简介

Elasticsearch 是一个高度可扩展且开源的全文检索和分析引擎。它可以让您快速且近实时地存储,检索以及分析海量数据。它通常用作那些具有复杂搜索功能和需求的应用的底层引擎或者技术。(我们得把MySQL中的数据给ES也存储一份,这样ES才能检索这些数据)

  • https://www.elastic.co/cn/what-is/elasticsearch
  • 全文搜索属于最常见的需求,开源的 Elasticsearch 是目前全文搜索引擎的首选。
  • 它可以快速地储存、搜索和分析海量数据。维基百科、Stack Overflow、Github 都采用它
  • Elastic 的底层是开源库 Lucene。但是,你没法直接用 Lucene,必须自己写代码去调用它的接口。
  • Elastic 是 Lucene 的封装,提供了 REST API 的操作接口,开箱即用。
  • REST API:天然的跨平台。
  • 官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html
  • 官方中文:https://www.elastic.co/guide/cn/elasticsearch/guide/current/foreword_id.html
  • 社区中文:
    • https://es.xiaoleilu.com/index.html
    • http://doc.codingdict.com/elasticsearch/0/

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

基本概念

在这里插入图片描述

类比MySQL数据库:

索引               =============           数据库
类型               =============           数据表
文档               =============           行记录(数据)
属性               =============           列名

一个 Elasticsearch 可以 包含多个 索引 ,相应的每个索引可以包含多个 类型 。 这些不同的类型存储着多个 文档 ,每个文档又有 多个 属性 。【这些文档都是json】

在这里插入图片描述

在这里插入图片描述

ElasticSearch概念-倒排索引

在这里插入图片描述

比如检索“红海特工行动”,会发现,4号记录命中了一次,1/2/3/5分别命中了两次,但是,5号记录是四个单词命中了两次,3号记录是三个单词命中了两次,那么3号记录的相关性得分就更高;查询出的结果会按照相关性得分从高到低排序。

安装

老师安装在虚拟机中,由于内存原因,我安装在Windows下

elasticsearch:7.4.2

https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.4.2-windows-x86_64.zip

elasticsearch.yml:

path.data: G:\elasticsearch\data
path.logs: G:\elasticsearch\logs
http.cors.enabled: true 
http.cors.allow-origin: "*"

jvm.options:

-Xms64m
-Xmx512m

在这里插入图片描述

kibana:7.4.2

https://artifacts.elastic.co/downloads/kibana/kibana-7.4.2-windows-x86_64.zip

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

基本命令

保存一个数据,保存在哪个索引的哪个类型下,指定用哪个唯一标识

PUT customer/external/1;在 customer 索引下的 external 类型下保存 1 号数据为

{ 
	"name": "John Doe"
}

在这里插入图片描述

PUT 和 POST 都可以,

  • POST 新增。如果不指定 id,会自动生成 id。指定 id 就会修改这个数据,并新增版本号
  • PUT 可以新增可以修改。PUT 必须指定 id;由于 PUT 需要指定 id,我们一般都用来做修改操作,不指定 id 会报错。

查询文档
在这里插入图片描述

在这里插入图片描述

ik 分词器

https://github.com/infinilabs/analysis-ik/releases?after=v6.4.2&page=11

放到G:\software\elasticsearch-7.4.2-windows-x86_64\elasticsearch-7.4.2\plugins目录下并解压,然后改目录名为analysis-ik

在这里插入图片描述

使用分词器对比:(默认分词器:standard)

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

能够看出不同的分词器,分词有明显的区别,所以以后定义一个索引不能再使用默认的 mapping 了,要手工建立 mapping, 因为要选择分词器。

自定义词库:

利用 nginx 发布静态资源,按照请求路径,创建对应的文件夹以及文件,放在nginx的html目录下

在这里插入图片描述

在这里插入图片描述

修改G:\software\elasticsearch-7.4.2-windows-x86_64\elasticsearch-7.4.2\plugins\analysis-ik\config\IKAnalyzer.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典 -->
	<entry key="ext_dict"></entry>
	 <!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords"></entry>
	<!--用户可以在这里配置远程扩展字典 -->
	<!-- http://192.168.56.10/fenci/myword.txt 80断口是nginx端口,把这个txt放在nginx中的html目录下 -->
	<entry key="remote_ext_dict">http://192.168.56.10/fenci/myword.txt</entry>
	<!--用户可以在这里配置远程扩展停止词字典-->
	<entry key="remote_ext_stopwords">words_location</entry>
</properties>

重启elasticsearch和kibana后,测试自定义的词库使用效果:

在这里插入图片描述

在这里插入图片描述

注意:

更新完成后,es 只会对新增的数据用新词分词。历史数据是不会重新分词的。如果想要历史数据重新分词。需要执行:

POST my_index/_update_by_query?conflicts=proceed

SpringBoot整合

在这里插入图片描述

在这里插入图片描述

最终选择 Elasticsearch-Rest-Client(elasticsearch-rest-high-level-client):

https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html

依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.atguigu.gulimall</groupId>
    <artifactId>gulimall-search</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>gulimall-search</name>
    <description>ElasticSearch检索服务</description>

    <properties>
        <elasticsearch.version>7.4.2</elasticsearch.version>
    </properties>

    <dependencies>
        <!-- 导入es的rest-high-level-client-->
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
            <version>7.4.2</version>
        </dependency>
    </dependencies>
</project>

配置类:

/**
 * 1、导入依赖
 * 2、编写配置,给容器中注入一个RestHighLevelClient
 * 3、参照API https://www.elastic.co/guide/en/elasticsearch/client/java-rest/current/java-rest-high.html
 */
@Configuration
public class ElasticSearchConfig {

    public static final RequestOptions COMMON_OPTIONS;

    static {
        RequestOptions.Builder builder = RequestOptions.DEFAULT.toBuilder();
//        builder.addHeader("Authorization", "Bearer " + TOKEN);
//        builder.setHttpAsyncResponseConsumerFactory(
//                new HttpAsyncResponseConsumerFactory
//                        .HeapBufferedResponseConsumerFactory(30 * 1024 * 1024 * 1024));
        COMMON_OPTIONS = builder.build();
    }

    @Bean
    public RestHighLevelClient esRestClient(
            @Value("${spring.elasticsearch.jest.uris}") String esUrl
    ) {
        //TODO 修改为线上的地址

        //final String hostname, final int port, final String scheme

///        RestClientBuilder builder = RestClient.builder(new HttpHost("192.168.56.10", 9200, "http"));

//        RestHighLevelClient client = new RestHighLevelClient(
//                RestClient.builder(
//                        new HttpHost("192.168.56.10", 9200, "http")));

        return new RestHighLevelClient(RestClient.builder(HttpHost.create(esUrl)));
    }

}
@EnableDiscoveryClient
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class GulimallSearchApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallSearchApplication.class, args);
    }

}
spring:
  elasticsearch:
    jest:
      uris: 127.0.0.1:9200

测试存储数据:

    @Test
    public void indexData() throws IOException {
        IndexRequest indexRequest = new IndexRequest("users");
        indexRequest.id("1");//数据的id,如果不设置会自动生成id
//        indexRequest.source("userName","zhangsan","age",18,"gender","男");
        User user = new User();
        user.setUserName("zhangsan");
        user.setAge(18);
        user.setGender("男");
        String jsonString = JSON.toJSONString(user);
        indexRequest.source(jsonString, XContentType.JSON);//要保存的内容

        //执行操作
        IndexResponse index = client.index(indexRequest, ElasticSearchConfig.COMMON_OPTIONS);

        //提取有用的响应数据
        System.out.println(index);
    }

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

将存储的东西转为JSON即可

在这里插入图片描述

测试复杂检索

    @Test
    public void searchData() throws IOException {
        //1、创建检索请求
        SearchRequest searchRequest = new SearchRequest();
        //指定索引
        searchRequest.indices("bank");
        //指定DSL,检索条件
        //SearchSourceBuilder sourceBuilde 封装的条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //1.1)、构造检索条件
//        sourceBuilder.query();
//        sourceBuilder.from();
//        sourceBuilder.size();
//        sourceBuilder.aggregation()
        sourceBuilder.query(QueryBuilders.matchQuery("address","mill"));

        //1.2)、按照年龄的值分布进行聚合
        TermsAggregationBuilder ageAgg = AggregationBuilders.terms("ageAgg").field("age").size(10);
        sourceBuilder.aggregation(ageAgg);

        //1.3)、计算平均薪资
        AvgAggregationBuilder balanceAvg = AggregationBuilders.avg("balanceAvg").field("balance");
        sourceBuilder.aggregation(balanceAvg);

        System.out.println("检索条件"+sourceBuilder.toString());
        searchRequest.source(sourceBuilder);

        //2、执行检索;
        SearchResponse searchResponse = client.search(searchRequest, ElasticSearchConfig.COMMON_OPTIONS);

        //3、分析结果 searchResponse
        System.out.println(searchResponse.toString());
//        Map map = JSON.parseObject(searchResponse.toString(), Map.class);
        //3.1)、获取所有查到的数据
        SearchHits hits = searchResponse.getHits();
        SearchHit[] searchHits = hits.getHits();
        for (SearchHit hit : searchHits) {
            /**
             * "_index": "bank",
             * 			"_type": "account",
             * 			"_id": "345",
             * 			"_score": 5.4032025,
             * 			"_source":
             */
//            hit.getIndex();hit.getType();hit.getId();
            String string = hit.getSourceAsString();
            Accout accout = JSON.parseObject(string, Accout.class);
            System.out.println("accout:"+accout);
        }

        //3.2)、获取这次检索到的分析信息;
        Aggregations aggregations = searchResponse.getAggregations();
//        for (Aggregation aggregation : aggregations.asList()) {
//            System.out.println("当前聚合:"+aggregation.getName());
            aggregation.get
//
//        }
        Terms ageAgg1 = aggregations.get("ageAgg");
        for (Terms.Bucket bucket : ageAgg1.getBuckets()) {
            String keyAsString = bucket.getKeyAsString();
            System.out.println("年龄:"+keyAsString+"==>"+bucket.getDocCount());
        }

        Avg balanceAvg1 = aggregations.get("balanceAvg");
        System.out.println("平均薪资:"+balanceAvg1.getValue());

//        Aggregation balanceAvg2 = aggregations.get("balanceAvg");
    }

同步与异步调用

在这里插入图片描述

在这里插入图片描述

参考

雷丰阳: Java项目《谷粒商城》Java架构师 | 微服务 | 大型电商项目.


本文完,感谢您的关注支持!


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

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

相关文章

【UE数字孪生学习笔记】 Apifox一体化接口测试平台

声明&#xff1a;部分内容来自于b站&#xff0c;知乎&#xff0c;慕课&#xff0c;公开课等的课件&#xff0c;仅供学习使用。如有问题&#xff0c;请联系删除。 部分内容来自UE官方文档&#xff0c;博客等 Apifox接口测试 Apifox 是集 API 文档、API 调试、API Mock、API 自动…

DDMA信号处理以及数据处理的流程---距离速度测量

Hello,大家好,我是Xiaojie,好久不见,欢迎大家能够和Xiaojie一起学习毫米波雷达知识,Xiaojie准备连载一个系列的文章—DDMA信号处理以及数据处理的流程,本系列文章将从目标生成、信号仿真、测距、测速、cfar检测、测角、目标聚类、目标跟踪这几个模块逐步介绍,这个系列的…

腾讯《地下城与勇士:起源》手游在部分安卓平台停止更新

原标题&#xff1a;因合约到期 《DNF手游》停止安卓平台更新 易采游戏网6月19日消息&#xff1a;《地下城与勇士&#xff1a;起源》(简称DNF手游)官方今天公告&#xff0c;因合作协议到期&#xff0c;自6月20日起&#xff0c;该游戏将不再在某些安卓应用商店提供。腾讯公司已经…

OpenAI 发布多模态 GPT-4 模型,会开创哪些新的研究方向?

作者&#xff1a;JioNLP 链接&#xff1a;https://www.zhihu.com/question/589640227/answer/2936760622 来源&#xff1a;知乎 著作权归作者所有。商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处。 短期看&#xff0c;GPT4 就是个终结者 。开创不了什么新的方…

Redis学习|Jedis、SpringBoot整合Redis

Jedis 我们要使用Java 来操作 Redis,知其然并知其所以然&#xff0c;授人以渔!学习不能急躁&#xff0c;慢慢来会很快!什么是Jedis 是 Redis 官方推荐的java连接开发工具!使用java 操作Redis 中间件!如果你要使用 java操作redis&#xff0c;那么一定要对Jedis 十分的熟悉! 1、…

C++初学者指南第一步---7.控制流(基础)

C初学者指南第一步—7.控制流&#xff08;基础&#xff09; 文章目录 C初学者指南第一步---7.控制流&#xff08;基础&#xff09;1.术语:表达式/语句Expressions表达式Statements语句 2.条件分支3.Switching(切换):基于值的分支4.三元条件运算符5.循环迭代基于范围的循环   C…

STM32人工智能检测-筛选机器人

前言 本文描述了一种使用STM32进行机器人筛选的办法。筛选对象是我的粉s&#xff0c;删选办法是瞪眼法。 问题现象 每次当我的STM32 向外界发出一篇新的的报文&#xff0c;总能在1H之内得到focus&#xff0c;格式如下 [title][body][tail]于是我对各个focus 我报文的对象进…

Midjourney和Stable Diffusion哪个更适合商业应用?

midjourney的绘画&#xff0c;在撰写有效的prompt需要精确地定义你想要展现的画面&#xff0c;详细描述越准确&#xff0c;生成出的图片结果也会越吻合你的预期。为了提升你midjourney的写作prompt的技巧&#xff0c;可以通过模仿他人的成功案例&#xff0c;亲自尝试编写&#…

UWA发布 | Unity手游性能年度蓝皮书

UWA本次发布的《2023-2024年度Unity手游性能蓝皮书》将汇总游戏行业使用Unity引擎进行手游开发过程中及游戏上线后的性能表现&#xff0c;从测试机型分布、引擎各模块开销、内存占用等方面剖析定位Unity手游性能瓶颈和趋势&#xff0c;反映了Unity手游行业的现状&#xff0c;帮…

202483读书笔记|《牵牛花浮世无篱笆:千代尼俳句250》——被红叶染红的只有一侧山坡之山 啊,单恋

202483读书笔记|《牵牛花浮世无篱笆&#xff1a;千代尼俳句250》——被红叶染红的只有一侧山坡之山 啊&#xff0c;单恋 春之句夏之句秋之句冬之句 历史读过的俳句列表: 202318读书笔记|《芭蕉芜村一茶&#xff1a;俳句三圣新译300》——樱花——让一整个春夜亮起来&#xff0…

MPLS静态配置实验(初学版)

实验拓扑 配置接口地址 配置OSPF协议 测试网络连通性 配置静态MPLS AR1&#xff1a; [R1]mpls lsr-id 1.1.1.1 [R1]mpls [R1-GigabitEthernet0/0/0]mpls [R1]static-lsp ingress wps destination 4.4.4.4 32 nexthop 10.1.12.2 outgoing-interface g0/0/0 out-label 100AR2 [R2…

【第20章】Vue实战篇之Vue Router(路由)

文章目录 前言一、使用Vue-Router1.安装2. 创建路由器实例3. 注册路由器插件4. 根组件 二、访问路由器1.理论2.使用3. 展示 三、嵌套路由(子路由)1. 准备文件2. 配置路由3. 菜单配置4. 展示 总结 前言 Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成&#xff0c;…

VMware RedHat虚拟机磁盘扩容(添加磁盘和扩展磁盘)

前言 自己的电脑上配一个虚拟机还是很有必要的&#xff0c;用起来比双系统方便一点&#xff0c;之前搞了100g的ubuntu没用到&#xff0c;后面重装redhat觉得随便搞个20g就够用了&#xff0c;后面用到之后就遇到磁盘不够用的情况&#xff0c;只能说情况允许的话&#xff0c;磁盘…

SambaLingo——教会大模型新语言

在当今数字化时代&#xff0c;语言不仅是沟通的桥梁&#xff0c;也是信息和知识传递的核心。尽管大模型&#xff08;LLMs&#xff09;在处理英语等主流语言方面取得了显著进展&#xff0c;但它们在理解和生成其他语言内容方面的能力却参差不齐。这种不平衡限制了技术在全球范围…

广告权重及出价解析

由于算法一直在不断改变&#xff0c;所以公式只能作为参考&#xff0c;不过核心是不变的。一、广告权重及出价解析 链接质量分CTR分值**CR分值&#xff08;点击率*转化率&#xff09;广告质量分广告出价*链接质量分我们的出价下一名产品的广告质量评分/我们的链接质量分0.01 …

SUSE linux的快照和恢复

snapper用于创建和管理文件系统快照&#xff0c;并在需要时实现回滚&#xff0c;它还可以用于创建用户数据的磁盘备份。snapper使用btrfs文件系统或者精简配置的被格式化成XFS或EXT4的LVM卷。snapper可以通过命令行或YaST来进行管理。 btrfs是一种copy-on-write文件系统&#x…

LoRA用于高效微调的基本原理

Using LoRA for efficient fine-tuning: Fundamental principles — ROCm Blogs (amd.com) 大型语言模型的低秩适配&#xff08;LoRA&#xff09;用于解决微调大型语言模型&#xff08;LLMs&#xff09;的挑战。GPT和Llama等拥有数十亿参数的模型&#xff0c;特定任务或领域的微…

easyexcel和poi版本冲突报错深入解析v2

easyexcel报错解决 问题 项目由poi改用easyexcel&#xff0c;报错如下&#xff1a; java.lang.NoSuchMethodError: ‘org.apache.poi.ss.usermodel.CellType org.apache.poi.ss.usermodel.Cell.getCellType()’ 原因 easyexcel中的poi和项目原本的poi版本冲突问题。 由于之前做…

双指针问题2

文章目录 1. 有效三角形的个数&#xff08;611&#xff09;2. 查找总价格为目标值的两个商品&#xff08;LCR179&#xff09;3. 三数之和&#xff08;15&#xff09;4. 四数之和&#xff08;18&#xff09; 1. 有效三角形的个数&#xff08;611&#xff09; 题目描述&#xff…

单元测试很难么?

前言 你可能会用单元测试框架&#xff0c;python的unittest、pytest&#xff0c;Java的Junit、testNG等。 那么你会做单元测试么&#xff01;当然了&#xff0c;这有什么难的&#xff1f; test_demo.py def inc(x): return x 1 def test_answer(): assert inc(3) 4 i…