Elasticsearch实现词云效果Demo

news2024/11/13 15:07:07

文章目录

  • 前言
  • 前期准备
    • springboot+Elasticsearch依赖
  • 思路
    • 准备数据
    • 查询数据
    • 处理文本
    • 样式处理
  • 具体实施
    • 数据准备
    • 创建索引
    • 数据存储
    • 进行查询
  • 踩坑记录
    • 聚合查询不生效问题
  • demo地址
  • 总结

前言

最近项目中使用Elasticsearch在做快速查询的功能,然后就想到了之前的一个项目中有一个词云的功能,就想用Elasticsearch实现一下词云的效果,实现思路很简单,目前这个demo已经写完了,透露一下很简陋,如何想要在项目中实际应用还需要改进。

前期准备

springboot+Elasticsearch依赖

版本我用的springboot 2.3.12.RELEASE对应的Elasticsearch是7.6.2

<!--        elasticsearch相关依赖-->
        <dependency>
            <groupId>org.elasticsearch</groupId>
            <artifactId>elasticsearch</artifactId>
        </dependency>
        <dependency>
            <groupId>org.elasticsearch.client</groupId>
            <artifactId>elasticsearch-rest-high-level-client</artifactId>
        </dependency>
        
        <!-- ikanalyzer 中文分词器  -->
        <dependency>
            <groupId>com.janeluo</groupId>
            <artifactId>ikanalyzer</artifactId>
            <version>2012_u6</version>
        </dependency>

在这里插入图片描述

思路

准备数据

将需要生成词云的文本数据存储到ES中。可以将文本拆分为单个词语,并将其作为文档的字段保存到ES中。

查询数据

使用ES的查询功能检索文档数据。可以根据业务需求编写查询语句,以获取需要的文本数据。

处理文本

将查询到的文本数据进行处理,例如去除停用词、统计词频等。

样式处理

这个不在本文章的范畴内,在上面的步骤就已经简单的实现一部分高频词的内容了,所以下面的这些是属于具体业务了,本文只提供一个思路和demo

  • 选择关键词:根据需求,可以根据词频进行排序,选择一定数量的高频词作为关键词。

  • 生成词云:使用词云生成工具库(如WordCloud)来生成词云图像。根据关键词的频率和重要性,在画布上布局词语,并设置相应的颜色、字体等样式。

  • 展示词云:将生成的词云图像展示在前端页面或保存为图片文件。如果在网页中展示,可以使用HTML和CSS来控制布局和样式。

具体实施

数据准备

就是单纯的准备数据阶段,使用下面这个数据中的数据随机生成一些句子,然后再使用Ik的工具包进行分词,分词以后存储到ES中

    static  final String[] CHINESE_WORDS = {
            "我", "你", "他", "她", "它",
            "是", "的", "在", "这", "那",
            "很", "真", "爱", "喜欢",
            "美丽", "快乐", "拥抱", "友情", "理解",
            "幸福", "梦想", "努力", "成功", "明天",
            "希望", "勇气", "坚定", "自信", "感恩",
            "热爱", "青春", "成长", "智慧", "创新",
            "开心", "失落", "放弃", "挑战", "困难",
            "奋斗", "拼搏", "汗水", "收获", "感动",
            "祝福", "寂寞", "无聊", "闲暇", "旅游",
            "信任", "包容", "尊重", "宽容", "耐心"
    };

   /**
     * @description: 使用IK对这些句子进行分词
     * @author: gepengjun
     * @date: 2023/9/8 10:09
     * @param: []
     * @return: java.util.List<java.lang.String>
     **/
    List<String> fenci() throws IOException {

            String text = "我喜欢使用IK分词器进行中文分词。";
        List<String> strings = generateRandomChineseSentences(20);
        String context="";
        for (String string : strings) {
            context+=string;
        }
        List<String> lists=new ArrayList<>();
        try (StringReader reader = new StringReader(context)) {
                IKSegmenter segmenter = new IKSegmenter(reader, true);
                Lexeme lexeme;
                while ((lexeme = segmenter.next()) != null) {
                    System.out.println(lexeme.getLexemeText());
                    lists.add(lexeme.getLexemeText());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

        return lists;
    }

  /**
     * @description: 生成句子的
     * @author: gepengjun
     * @date: 2023/9/8 10:09
     * @param: [numSentences]生成多少条
     * @return: java.util.List<java.lang.String>
     **/
    private static List<String> generateRandomChineseSentences(int numSentences) {
        List<String> sentences = new ArrayList<>();

        Random random = new Random();

        for (int i = 0; i < numSentences; i++) {
            int numWords = random.nextInt(10) + 5; // 每个句子包含的词语数量范围为 5-14

            StringBuilder sb = new StringBuilder();
            for (int j = 0; j < numWords; j++) {
                int index = random.nextInt(CHINESE_WORDS.length);
                sb.append(CHINESE_WORDS[index]);
            }

            String sentence = sb.toString();
            sentences.add(sentence);
        }

        return sentences;
    }

创建索引

存储数据前要先创建索引,在ES中索引你可以理解为数据库中的表

    @Test
    void createIndex(){
        // 创建ES连接
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("116.204.118.226", 9200, "http")));

        try {
            // 创建索引请求
            CreateIndexRequest request = new CreateIndexRequest("wordcloud");//简单理解就是建表

            // 设置索引的设置
            request.settings(Settings.builder()
                    .put("index.number_of_shards", 1)
                    .put("index.number_of_replicas", 1));

            // 设置索引的映射
            XContentBuilder mapping = XContentFactory.jsonBuilder()
                    .startObject()
                    .startObject("properties")
                    .startObject("context") //建表字段的过程
                    .field("type", "text")
                    .startObject("keyword") // 添加一个名为 "keyword" 的子字段
                    .field("type", "keyword") // 子字段类型为 keyword
                    .endObject()
                    .endObject()
                    .endObject()
                    .endObject();
            request.mapping("_doc",mapping);

            // 发送创建索引请求
            client.indices().create(request, RequestOptions.DEFAULT);

            System.out.println("索引创建成功!");

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭ES连接
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

注意这里,后面会用到
在这里插入图片描述

数据存储

注意我这些操作都是在单元测试中进行的

    @Test
    void insertData() throws IOException {
		// 创建一个 RestHighLevelClient 对象,用于与 Elasticsearch 进行通信
		RestHighLevelClient client = new RestHighLevelClient(
		        RestClient.builder(new HttpHost("localhost", 9200, "http")));
		
		// 创建一个 BulkRequest 对象,用于批量操作请求
		BulkRequest request = new BulkRequest();
		
		// 调用 fenci() 方法获取分词结果列表
		List<String> strings = fenci();
		
		// 遍历分词结果列表,将每个分词作为一个文档添加到 BulkRequest 中
		for (String word: strings) {
		    // 创建一个 IndexRequest 对象,并指定要添加到的索引名称和文档内容
		    request.add(new IndexRequest("wordcloud").source("context", word));
		}
		
		// 执行批量操作请求,并获取响应
		BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
        if (response.hasFailures()) {
            // 处理错误情况
            System.out.println("添加失败---------------------");
        } else {
            // 处理成功情况
            System.out.println("添加成功");
        }
    }

进行查询

这里使用了es的聚合查询,查询该索引下出现频率最高的前20个单词

    @Test
    void wrodCloud(){
        // 创建ES连接
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(new HttpHost("localhost", 9200, "http")));

        try {
            // 构建搜索请求
            SearchRequest request = new SearchRequest("wordcloud");
            SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
            sourceBuilder.query(QueryBuilders.matchAllQuery());
            sourceBuilder.size(0); // 设置为0以仅返回聚合结果
            sourceBuilder.timeout(TimeValue.timeValueMinutes(1));

            // 添加词频统计的聚合
            sourceBuilder.aggregation(
                    AggregationBuilders.terms("word_count")
                            .field("context.keyword")
                            .size(20)); // 返回频率最高的 20 个词语

            request.source(sourceBuilder);

            // 执行搜索请求
            SearchResponse response = client.search(request, RequestOptions.DEFAULT);
            ParsedStringTerms wordCount = response.getAggregations().get("word_count");
            for (Terms.Bucket bucket : wordCount.getBuckets()) {
                String word = bucket.getKeyAsString();
                long frequency = bucket.getDocCount();
                System.out.println("热门单词:"+word);
                System.out.println("出现次数:"+frequency);
                System.out.println("——————————————————————————————");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭ES连接
            try {
                client.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

可以看到查询出来了20个单词,以及出现的频率,这样我们将这些单词以及频率进行一些简单的处理就能获得它们的占比,然后返回到前端展示,至于前端要使用什么用的控件或者框架是另一回事了,因为这些数据是准备好的。
在这里插入图片描述

踩坑记录

聚合查询不生效问题

这个问题就是上面创建索引中截图圈出来的部分,就是当我们对文本类型的数据进行聚合查询是需要设置它的子字段有一个keywrod类型的,然后在查询的时候指定这个(字段名.子字段名),这种方式就能正常的使用es的聚合查询了。
在 Elasticsearch 中,当需要对文本类型的字段进行聚合查询时,需要使用额外的 “keyword” 类型的子字段。这样做的目的是为了将文本数据转换为可进行聚合操作的结构。

设置 “keyword” 子字段的步骤如下:

  1. 创建索引时,在字段的映射中为文本字段添加一个子字段。
  2. 子字段的类型设置为 “keyword”,表示它是一个非分词的字符串类型。
  3. 可以为子字段指定任意的名称,不一定非得叫 “keyword”。

通过将字段的类型设置为 “keyword”,Elasticsearch 将保存原始文本数据,并允许对该子字段进行精确的分组统计操作,实现对文本字段的聚合查询。

demo地址

Demo地址

总结

关于使用这个es实现的这个效果,个人认为这只是一种方案,还有其它的,这里是直接使用的分词工具包,es上还可以安装分词插件,所以我的这种不一定是最好的,这是一种简单的方案希望大家不要被我的这种给迷惑了

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

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

相关文章

航空航天行业的MES系统解决方案

航空航天行业的制造执行系统&#xff08;MES&#xff09;解决方案是为了满足这个高度复杂、高度规定、高度技术要求的行业而设计的。MES系统在航空航天制造中发挥着关键的作用&#xff0c;帮助企业提高生产效率、降低成本、确保质量合规性&#xff0c;并实现生产过程的可视化和…

免费小程序商城搭建之b2b2c o2o 多商家入驻商城 直播带货商城 电子商务b2b2c o2o 多商家入驻商城 直播带货商城 电子商务

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…

基于SpringBoot+Vue实现的前后端分离的外卖点餐系统源代码+数据库

该项目是一个前后端分离的外卖点餐系统&#xff0c;项目后端采用SpringBoot开发。 完整代码下载地址&#xff1a;基于SpringBootVue实现的前后端分离的外卖点餐系统源代码数据库 功能模块 基础数据模块 分类管理员工管理套餐管理 点餐业务模块 店铺营业状态微信登录缓存商品…

数字孪生背后:谁在构建真实的数字世界?

如果说过去人们对于数字孪生的定位仅仅是真实世界的数字映像&#xff0c;那么如今&#xff0c;在映像之外&#xff0c;于众多的产业之中&#xff0c;它也更在通过更加复杂的设计和 技术成为现实世界的新数字调控器。 在这艘向前行进的航船上&#xff0c;改变的不仅是前方更加…

【录用案例】CCF-C类,1/2区SCIEI,3个月14天录用,30天见刊,11天检索

计算机科学类SCI&EI 【期刊简介】IF&#xff1a;5.5-6.0&#xff0c;JCR1/2区&#xff0c;中科院2区 【检索情况】SCI&EI 双检&#xff08;CCF-C类&#xff09; 【征稿领域】边缘计算、算法与机器学习的结合研究 录用案例&#xff1a;3个月14天录用&#xff0c;录用…

二维码智慧门牌管理系统:解决地理地址标准化的革新方案

文章目录 前言一、地理地址标准化难题二、地理地址标准化解决方案三、统一治理多源地址四、地址数据清洗和标准化五、提升协作和效率 前言 随着信息化社会的快速发展&#xff0c;各个业务系统都涉及地址问题&#xff0c;然而每个平台的地址规范又不统一&#xff0c;这给地址管…

最新报告!TikTok 市场小家电大商机,GMV破亿的爆款如何复制?

近期&#xff0c;新锐小家电品牌Gaabor空气炸锅在东南亚卖爆了&#xff0c;单款商品GMV短时间内突破两亿&#xff0c;在印尼、泰国、马来西亚、菲律宾、越南均开设本土TikTok 小店&#xff0c;增长势头还在持续。 但Gaabor并不是个例。 整个东南亚家电市场规模增长迅速&#…

vue3+ts+vite项目引入echarts,vue3项目echarts组件封装

概述 技术栈&#xff1a;Vue3 Ts Vite Echarts 简介&#xff1a; 图文详解&#xff0c;教你如何在Vue3项目中引入Echarts&#xff0c;封装Echarts组件&#xff0c;并实现常用Echarts图例 文章目录 概述一、先看效果1.1 静态效果1.2 动态效果 二、话不多数&#xff0c;引入 …

Polarion创建项目

创建项目添加用户删除用户项目访问

消息中间件(一)

文章目录 消息中间件什么是中间件&#xff1f;为什么使用MQ&#xff1f;应用场景&#xff1f; JMS和AMQPJMSAMQPJMS和AMQP的区别 消息队列产品 消息中间件 什么是中间件&#xff1f; MQ全称为Message Queue&#xff0c;消息队列是应用程序和应用程序之间的通信方法。 中间件是…

大模型优化:RAG还是微调?

引言 随着人们对大型语言模型 (LLM) 的兴趣激增&#xff0c;许多开发人员和组织正忙于利用其能力构建应用程序。然而&#xff0c;当开箱即用的预训练LLM没有按预期或希望执行时&#xff0c;如何提高LLM申请的性能的问题。最终我们会问自己&#xff1a;我们应该使用检索增强生成…

Vue中如何实现城市3D分布图

cityfenbu.vue <template><div ><el-card class"seriesmap-box-card"><div slot"header" class"clearfix"><span>城市分布图 (点击可下钻到县)</span></div><div><div class"series-ma…

不出意外的话,2023年是AI大模型元年

这两天听的最多的新闻莫过于&#xff0c;谁谁谁&#xff08;AI 大模型&#xff09;面向全社会开放使用&#xff0c;文心一言、WPSAI、讯飞星火、百川智能等等&#xff0c;2023年&#xff0c;AI大模型注定在历史上增添了浓妆淡抹的一幕&#xff0c;未来 AI 将与各个软件应用如影…

RPC协议交互流程

文章目录 RPC特性RPC实现RPC交互流程RPC交互时序图RPC交互流程 RPC&#xff08;Remote Procedure Call&#xff0c;远程过程调用&#xff09; 是一种分布式计算的通信协议和编程模型&#xff0c;用于不同计算机或进程之间进行远程通信。它允许一个计算机程序&#xff08;通常是…

TOWE新能源电动汽车充电延长线,解决户外充电距离过短烦恼

随着新能源汽车市场的日益繁荣&#xff0c;越来越多的车主开始关注充电设备的便利性。为了满足广大车主的充电需求&#xff0c;同为科技&#xff08;TOWE&#xff09;荣誉推出全新16A三芯大功率新能源电动汽车充电延长电源线。这款产品采用优质材料&#xff0c;结构合理&#x…

@Value,@Autowired,@Qualifier

Value 当属性的类型是简单类型时&#xff0c;可以使用Value注解进行注入。 package com.powernode.spring6.bean4;import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component;Component public class User {Value(value …

NASM编译器之下载安装使用

NASM的下载和安装 每种处理器都可能会有自己的汇编语言编译器&#xff0c;而对于同一款处理器来说&#xff0c;针对不同的平台(比如Windows和Linux&#xff09;&#xff0c;也会有不同版本的汇编语言编译器。 现存的汇编语言编译器有多种&#xff0c;用得比较多的有 MASM、FA…

如何加快跨国传输大文件的速度?

在当今的信息化社会&#xff0c;数据已经成为各行各业的重要资产&#xff0c;而数据的传输和交换则是数据价值的体现。在很多场景中&#xff0c;我们需要跨国传输大文件&#xff0c;比如政府、军队、金融、医疗等涉密行业&#xff0c;或者跨国、跨区域的企业合作。然而&#xf…

浅谈安科瑞ADL400系列导轨电能表在沙特电力物联网平台中的应用

1.项目概述&#xff1a;Project Overview 沙特客户需要对小区住宅&#xff0c;及商铺进行用户端电能计量&#xff0c;管理。需要安装三相交流电表监测电能数据&#xff0c;并上传到后台系统进行统一监控管理。安科瑞推荐电力物联网平台&#xff0c;可以通过云端界面和APP查看不…

Python中文字体包下载经历(经验分享)

故事背景 python解释器需要中文字体包&#xff0c;我找了半天网络上的中文字体包&#xff0c;每一个过程都非常繁琐。 都是先注册&#xff0c;在安装他们的软件&#xff0c;软件安装好后下载&#xff0c;下载的还不是字体包格式的文件&#xff0c;反正就是在欺负小白。 解决…