微服务Day7学习-数据聚合、同步、补全

文章目录

  • 数据聚合
    • 聚合分类
  • 自动补全
    • DSL实现Bucket聚合
    • DSL实现Metrics聚合
    • RestAPI实现聚合
    • 多条件聚合
    • 对接前端接口
    • 拼音分词器
    • 自定义分词器
    • 自动补全查询
    • 实现酒店搜索框自动补全
  • 数据同步
    • 数据同步思路分析
    • 利用mq实现mysql与elasticsearch数据同步
  • 集群
    • 介绍
    • 搭建ES集群

数据聚合

聚合分类

自动补全

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

DSL实现Bucket聚合

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

DSL实现Metrics聚合

在这里插入图片描述

RestAPI实现聚合

在这里插入图片描述
测试类

    @Test
    void testAggregation() throws IOException {
        //1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备DSL
        //2.1 设置size
        request.source().size(0);
        //2.2 聚合
        request.source().aggregation(AggregationBuilders
                .terms("brandAgg")
                .field("brand")
                .size(20));
        //3.发出请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //4.解析结果
        System.out.println(response);
    }

在这里插入图片描述

    @Test
    void testAggregation() throws IOException {
        //1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备DSL
        //2.1 设置size
        request.source().size(0);
        //2.2 聚合
        request.source().aggregation(AggregationBuilders
                .terms("brandAgg")
                .field("brand")
                .size(20));
        //3.发出请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        //4.解析结果
        Aggregations aggregations = response.getAggregations();
        //4.1 根据聚合名称获取聚合结果
        Terms brandTerms = aggregations.get("brandAgg");
        //4.2 获取buckets
        List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
        //4.3 遍历
        for (Terms.Bucket bucket : buckets) {
            //4.4获取key
            String key = bucket.getKeyAsString();
            System.out.println(key);
        }
    }

多条件聚合

在这里插入图片描述
Service实现类中

    @Override
    public Map<String, List<String>> filters() {
        //1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备DSL
        //2.1 设置size
        request.source().size(0);
        //2.2 聚合
        buildAggregation(request);
        //3.发出请求
        SearchResponse response = null;
        try {
            response = client.search(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        //4.解析结果
        Map<String, List<String>> result = new HashMap<>();
        Aggregations aggregations = response.getAggregations();
        //4.1 根据名称获取品牌结果 并放入map
        List<String> brandList = getAggByName(aggregations,"brandAgg");
        result.put("品牌", brandList);
        List<String> cityList = getAggByName(aggregations,"cityAgg");
        result.put("城市", cityList);
        List<String> starList = getAggByName(aggregations,"starAgg");
        result.put("星级", starList);
        return result;
    }

    private List<String> getAggByName(Aggregations aggregations,String aggName) {
        //4.1 根据聚合名称获取聚合结果
        Terms brandTerms = aggregations.get(aggName);
        //4.2 获取buckets
        List<? extends Terms.Bucket> buckets = brandTerms.getBuckets();
        //4.3 遍历
        List<String> brandList = new ArrayList<>();
        for (Terms.Bucket bucket : buckets) {
            //4.4获取key
            String key = bucket.getKeyAsString();
            brandList.add(key);
        }
        return brandList;
    }

    private void buildAggregation(SearchRequest request) {
        request.source().aggregation(AggregationBuilders
                .terms("brandAgg")
                .field("brand")
                .size(100));
        request.source().aggregation(AggregationBuilders
                .terms("cityAgg")
                .field("city")
                .size(100));
        request.source().aggregation(AggregationBuilders
                .terms("starAgg")
                .field("starName")
                .size(100));
    }

对接前端接口

在这里插入图片描述

拼音分词器

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

自定义分词器

在这里插入图片描述

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

自动补全查询

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

实现酒店搜索框自动补全

在这里插入图片描述
DSK代码

DELETE /hotel
# 酒店数据索引库
PUT /hotel
{
  "settings": {
    "analysis": {
      "analyzer": {
        "text_anlyzer": {
          "tokenizer": "ik_max_word",
          "filter": "py"
        },
        "completion_analyzer": {
          "tokenizer": "keyword",
          "filter": "py"
        }
      },
      "filter": {
        "py": {
          "type": "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": {
      "id":{
        "type": "keyword"
      },
      "name":{
        "type": "text",
        "analyzer": "text_anlyzer",
        "search_analyzer": "ik_smart", 
        "copy_to": "all"
      },
      "address":{
        "type": "keyword",
        "index": false
      },
      "price":{
        "type": "integer"
      },
      "score":{
        "type": "integer"
      },
      "brand":{
        "type": "keyword",
        "copy_to": "all"
      },
      "city":{
        "type": "keyword"
      },
      "starName":{
        "type": "keyword"
      },
      "business":{
        "type": "keyword",
        "copy_to": "all"
      },
      "location":{
        "type": "geo_point"
      },
      "pic":{
        "type": "keyword",
        "index": false
      },
      "all":{
        "type": "text",
        "analyzer": "text_anlyzer",
        "search_analyzer": "ik_smart"
      },
      "suggestion":{
          "type": "completion",
          "analyzer": "completion_analyzer"
      }
    }
  }
}

GET /hotel/_search
{
  "query": {
    "match_all": {}
  }
}

GET /hotel/_search
{
  "suggest": {
    "suggestions": {
      "text": "",
      "completion": {
        "field": "suggestion",
        "skip_duplicates": true,
        "size": 10
      }
    }
  }
}

修改实体类

@Data
@NoArgsConstructor
public class HotelDoc {
    private Long id;
    private String name;
    private String address;
    private Integer price;
    private Integer score;
    private String brand;
    private String city;
    private String starName;
    private String business;
    private String location;
    private String pic;
    private Object distance;
    private Boolean isAD;
    private List<String> suggestion;

    public HotelDoc(Hotel hotel) {
        this.id = hotel.getId();
        this.name = hotel.getName();
        this.address = hotel.getAddress();
        this.price = hotel.getPrice();
        this.score = hotel.getScore();
        this.brand = hotel.getBrand();
        this.city = hotel.getCity();
        this.starName = hotel.getStarName();
        this.business = hotel.getBusiness();
        this.location = hotel.getLatitude() + ", " + hotel.getLongitude();
        this.pic = hotel.getPic();
        if (this.business.contains("/")){
            //business有多个点,需要切割
            String[] arr = this.business.split("/");
            //添加元素
            this.suggestion = new ArrayList<>();
            this.suggestion.add(this.brand);
            Collections.addAll(this.suggestion, arr);
        }else {
            this.suggestion = Arrays.asList(this.brand,this.business);
        }
    }
}

在这里插入图片描述
建立测试类

    @Test
    void testSuggest() throws IOException {
        //1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备DSL
        request.source().suggest(new SuggestBuilder().
                addSuggestion("suggestions", SuggestBuilders
                        .completionSuggestion("suggestion")
                        .prefix("h")
                        .skipDuplicates(true)
                        .size(10)
                ));
        //3.发起请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        ///4.解析结果
        System.out.println(response);
    }

在这里插入图片描述
测试类

    @Test
    void testSuggest() throws IOException {
        //1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备DSL
        request.source().suggest(new SuggestBuilder().
                addSuggestion("suggestions", SuggestBuilders
                        .completionSuggestion("suggestion")
                        .prefix("h")
                        .skipDuplicates(true)
                        .size(10)
                ));
        //3.发起请求
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        ///4.解析结果
        Suggest suggest = response.getSuggest();
        //4.1根据补全查询名称获取补全结果
        CompletionSuggestion suggestions = suggest.getSuggestion("suggestions");
        //4.2 获取options
        List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
        //4.3 遍历
        for (CompletionSuggestion.Entry.Option option : options) {
            String text = option.getText().toString();
            System.out.println(text);
        }
    }

在这里插入图片描述

    @Override
    public List<String> getSuggestions(String prefix) {
        //1.准备Request
        SearchRequest request = new SearchRequest("hotel");
        //2.准备DSL
        request.source().suggest(new SuggestBuilder().
                addSuggestion("suggestions", SuggestBuilders
                        .completionSuggestion("suggestion")
                        .prefix(prefix)
                        .skipDuplicates(true)
                        .size(10)
                ));
        //3.发起请求
        SearchResponse response = null;
        try {
            response = client.search(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        ///4.解析结果
        Suggest suggest = response.getSuggest();
        //4.1根据补全查询名称获取补全结果
        CompletionSuggestion suggestions = suggest.getSuggestion("suggestions");
        //4.2 获取options
        List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
        //4.3 遍历
        List<String> list = new ArrayList<>(options.size());
        for (CompletionSuggestion.Entry.Option option : options) {
            String text = option.getText().toString();
            list.add(text);
        }
        return list;
    }

数据同步

数据同步思路分析

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

利用mq实现mysql与elasticsearch数据同步



声明excahnge、queue、RoutingKey

public class MqConstants {
    //交换机
    public final  static String HOTEL_EXCHANGE = "hotel.topic";
    //新增修改的队列
    public final  static String HOTEL_INSERT_QUEUE = "hotel.insert.queue";
    //删除队列
    public final  static String HOTEL_DELETE_QUEUE = "hotel.delete.queue";
    //新增获修改RoutingKey
    public final  static String HOTEL_INSERT_KEY = "hotel.insert";
    //删除的RoutingKey
    public final  static String HOTEL_DELETE_KEY = "hotel.delete";
}

@Configuration
public class MqConfig {
    @Bean
    public TopicExchange topicExchange(){
        return new TopicExchange(MqConstants.HOTEL_EXCHANGE,true,false);
    }
    @Bean
    public Queue insertQueue(){
        return new Queue(MqConstants.HOTEL_INSERT_QUEUE,true);
    }
    @Bean
    public Queue deleteQueue(){
        return new Queue(MqConstants.HOTEL_DELETE_QUEUE,true);
    }
    @Bean
    public Binding insertQueueBinding(){
        return BindingBuilder.bind(insertQueue()).to(topicExchange()).with(MqConstants.HOTEL_INSERT_KEY);
    }
    @Bean
    public Binding deleteQueueBinding(){
        return BindingBuilder.bind(deleteQueue()).to(topicExchange()).with(MqConstants.HOTEL_DELETE_KEY);
    }
}

yaml配置

  rabbitmq:
    host: xxx.xxx.x.xxx(主机地址)
    port: 5672
    username: itcast
    password: 123321
    virtual-host: /

在hotel-admin中增、删、改业务中完成消息发送
mq组件

@Component
public class HotelListener {
    @Autowired
    private IHotelService hotelService;
    /**
     * 监听酒店新增或修改的业务
     * @param id
     */
    @RabbitListener(queues = MqConstants.HOTEL_INSERT_QUEUE)
    public void listenHotelInsertOrUpdate(Long id){
        hotelService.insertById(id);
    }

    /**
     * 监听酒店删除的业务
     * @param id
     */
    @RabbitListener(queues = MqConstants.HOTEL_DELETE_QUEUE)
    public void listenHotelDelete(Long id){
        hotelService.deleteById(id);
    }
}

实现类

    @Autowired
    private RabbitTemplate rabbitTemplate;
        @PostMapping
    public void saveHotel(@RequestBody Hotel hotel){
        hotelService.save(hotel);
        rabbitTemplate.convertAndSend(MqConstants.HOTEL_EXCHANGE, MqConstants.HOTEL_INSERT_KEY, hotel.getId());
    }

    @PutMapping()
    public void updateById(@RequestBody Hotel hotel){
        if (hotel.getId() == null) {
            throw new InvalidParameterException("id不能为空");
        }
        hotelService.updateById(hotel);
        rabbitTemplate.convertAndSend(MqConstants.HOTEL_EXCHANGE, MqConstants.HOTEL_INSERT_KEY, hotel.getId());
    }

    @DeleteMapping("/{id}")
    public void deleteById(@PathVariable("id") Long id) {
        hotelService.removeById(id);
        rabbitTemplate.convertAndSend(MqConstants.HOTEL_EXCHANGE, MqConstants.HOTEL_DELETE_KEY, id);

    }

在hotel-demo中完成消息监听,并更新elasticsearch中的数据

    @Override
    public void deleteById(Long id) {
        //1.准备Request
        DeleteRequest request = new DeleteRequest("hotel",id.toString());
        //2.准备发送请求
        try {
            client.delete(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public void insertById(Long id) {
        //0.根据id查询酒店数据
        Hotel hotel = getById(id);
        //转换文档类型
        HotelDoc hotelDoc = new HotelDoc(hotel);
        //1.准备Request
        IndexRequest request = new IndexRequest("hotel").id(hotel.getId().toString());
        //2.准备JSON文档
        request.source(JSON.toJSONString(hotelDoc), XContentType.JSON);
        //3.准备发送请求
        try {
            client.index(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

集群

介绍

在这里插入图片描述

搭建ES集群

version: '2.2'
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.12.1
    container_name: es01
    environment:
      - node.name=es01
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es02,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data01:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - elastic
  es02:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.12.1
    container_name: es02
    environment:
      - node.name=es02
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data02:/usr/share/elasticsearch/data
    networks:
      - elastic
  es03:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.12.1
    container_name: es03
    environment:
      - node.name=es03
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es02
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data03:/usr/share/elasticsearch/data
    networks:
      - elastic

volumes:
  data01:
    driver: local
  data02:
    driver: local
  data03:
    driver: local

networks:
  elastic:
    driver: bridge

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电拖基础JIAOXUE

1.最简单的TT马达&#xff0c;实际就是一个减速电机&#xff1a; 减速箱的内部包含了一组齿轮。在实际的使用中&#xff0c;绝大部分的电动机都要和减速箱配合使用&#xff0c;因为一般的电机转速都在每分钟几千转甚至1万转以上&#xff0c;而在实际的使用中并不需要这么快的转…

RN:Error: /xxx/android/gradlew exited with non-zero code: 1

问题 执行 yarn android 报错&#xff1a; 解决 这个大概率是缓存问题&#xff0c;我说一下我的解决思路 1、yarn doctor 2、根据黄色字体提示&#xff0c;说我包版本不对&#xff08;但是这个是警告应该没事&#xff0c;但是我还是装了&#xff09; npx expo install --…

Lodop 实现局域网打印

文章目录 前言一、Lodop支持打印的方式lodop 打印方式一般有3种&#xff1a;本地打印局域网集中打印广域网AO打印 二、集成步骤查看lodop 插件的服务端口&#xff1a;查看ip后端提供接口返回ip&#xff0c;前端动态获取最后步骤 前言 有时候会根据不同的ip来获取资源文件&…

计算机网络 期末复习(谢希仁版本)第6章

DNS采用UDP。 DHCP 给运行服务器软件、且位置固定的计算机指派一个永久地址&#xff0c;给运行客户端软件的计算机分配一个临时地址

文件无法在当前环境下执行在 x86_64 系统上运行 ARM 可执行文件

目录 遇到的问题是由于"..."文件无法在当前环境下执行。这个错误通常是因为二进制文件的格式不兼容&#xff0c;可能是因为它是为不同的架构编译的。例如&#xff0c;如果二进制文件是为 x86 架构编译的&#xff0c;但你在 ARM 设备上尝试运行它&#xff0c;就会出现…

语言模型测试系列【9】

语言模型 文心一言讯飞星火通义千问2.5豆包360智脑百小应腾讯元宝KimiC知道 好长时间没有做语言模型的测试了&#xff0c;一方面是没有好的素材&#xff0c;各模型都在升级优化&#xff0c;而且频率很高&#xff1b;另一方面近期在阅读和学习其他的知识&#xff0c;所以更的也…

Typora编辑的markdown文档莫名其妙消失或未保存--解决方案【亲测可行】

由于误触键盘导致文件关闭&#xff0c;打开文件之后发现里面文字全没了~气死了&#xff01;&#xff01;&#xff01;&#xff01; 可以通过如下方法解决&#xff01; 一、打开typora 二、【文件】-【偏好设置】 三、点击恢复未保存的草稿&#xff0c;找到最近的文件复制粘贴…

针对AlGaN/GaN高电子迁移率晶体管的显式表面电势计算和紧凑电流模型

来源&#xff1a;An Explicit Surface Potential Calculation and Compact Current Model for AlGaN/GaN HEMTs&#xff08;EDL 15年&#xff09; 摘要 在本文中,我们提出了一种新的紧凑模型,用于基于费米能级和表面电位的显式解来描述AlGaN/GaN高电子迁移率晶体管。该模型计算…

【LLM】度小满金融大模型技术创新与应用探索

note 从通用大模型到金融大模型金融大模型的训练技术创新金融大模型的评测方法创新金融大模型的应用实践创新总结&#xff1a;金融大模型迭代路径 一、轩辕大模型 二、垂直大模型训练 1. 数据准备 数据质量是模型效果的保障。首先数据要丰富&#xff0c;这是必备的条件。我们…

hcache缓存查看工具

1、hcache概述 hcache是基于pcstat的&#xff0c;pcstat可以查看某个文件是否被缓存和根据进程pid来查看都缓存了哪些文件。hcache在其基础上增加了查看整个操作系统Cache和根据使用Cache大小排序的特性。官网:https://github.com/silenceshell/hcache 2、hcache安装 2.1下载…

Python Flask 入门开发

Python基础学习&#xff1a; Pyhton 语法基础Python 变量Python控制流Python 函数与类Python Exception处理Python 文件操作Python 日期与时间Python Socket的使用Python 模块Python 魔法方法与属性 Flask基础学习&#xff1a; Python中如何选择Web开发框架&#xff1f;Pyth…

【Tool】Matlab 数据分析可视化

一、问题描述 近期围绕imu总是出现问题&#xff0c;自己整理了一下将数据可视化的工具 二、imu 类 1. 待处理数据格式 # yaw roll pitch time -2.08131 -0.0741765 0.0200713 121.281000000 -2.08724 -0.0745256 0.0197222 121.301000000 -2.093 -0.075747…

【机器学习基础】Python编程01:五个实用练习题的解析与总结

Python是一种广泛使用的高级编程语言,它在机器学习领域中的重要性主要体现在以下几个方面: 简洁易学:Python语法简洁清晰,易于学习,使得初学者能够快速上手机器学习项目。 丰富的库支持:Python拥有大量的机器学习库,如scikit-learn、TensorFlow、Keras和PyTorch等,这些…

吴恩达2022机器学习专项课程C2W3:2.24 机器学习实践建议(决定下一步做什么模型评估模型选择交叉验证)

目录 引言一、绘图评估模型的局限性二、使用测试集评估模型1.线性回归2.逻辑回归3.测试误差与泛化误差 三、测试集评估模型存在的问题1.评估模型流程2.流程存在的问题 四、解决问题1.训练集分割成三段2.计算交叉验证集的误差 五、重新评估模型1.线性回归模型2.神经网络模型3.评…

Android 14.0 Settings主页面去掉自定义您的设备等菜单相关功能

1.前言 在14.0的系统rom产品定制化开发中,在系统Settings主页面的主菜单中,在测试某些功能的时候,比如开启护眼模式和改变系统密度会在主菜单第一项的网络菜单头部增加 自定义您的设备和设置护眼模式时间安排 等等相关的设置模块 这对于菜单布局显示相当不美观,所以根据系…

SpringBoot+Redis发送短信

SpringBootRedis发送短信 pom.xml <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId&g…

【TB作品】 51单片机8x8点阵显示滚动汉字仿真

功能 题目5基于51单片机LED8x8点阵显示 流水灯 直接滚动显示HELLO 直接滚动显示老师好 代码 void main( void ) {/** 移位后&#xff0c;右边的是第一个595&#xff0c;接收0X02&#xff0c;显示出0X02* 移位后&#xff0c;左边的是第2个595&#xff0c;接收0Xfe&#xff0c…

git 的基本操作 Master and branch的版本合并 @ VS 1019

前言&#xff1a; 在VS 2019有git 的可视化管理,但&#xff0c;感觉微软其实就是在git上包了一层。版本冲突后&#xff0c;还是要靠git 的命令行代码搞。本文记录了一次&#xff0c;branch和master的版本合并的过程。作为&#xff0c;后续的参考。 【注意&#xff0c;这个是一…

最短路径——迪杰斯特拉与弗洛伊德算法

一.迪杰斯特拉算法 首先对于最短路径来说&#xff1a;从vi-vj的最短路径&#xff0c;不用非要经过所有的顶点&#xff0c;只需要找到路径最短的路径即可&#xff1b; 那么迪杰斯特拉的算法&#xff1a;其实也就与最小生成树的思想类似&#xff0c;找到较小的&#xff0c;然后…

JavaScript 学习笔记 总结

回顾&#xff1a; Web页面标准 页面结构&#xff1a;HTML4、HTML5页面外观和布局&#xff1a;CSS页面行为&#xff1a;JavaScript强调三者的分离前后端分离开发模式 响应式设计Bootstrap框架入门 Bootstrap总结 基础 下载和使用基础样式&#xff1a;文本样式、图片样式、表格…