生产环境_从数据到层级结构JSON:使用Spark构建多层次树形数据_父子关系生成

news2024/11/24 12:40:12

代码补充了!兄弟萌

造的样例数据

val data = Seq(
  ("USA", "Male", "Asian", "Chinese"),
  ("USA", "Female", "Asian", "Chinese"),
  ("USA", "Male", "Black", "African"),
  ("USA", "Female", "Black", "African"),
  ("USA", "Male", "White", "European"),
  ("USA", "Female", "White", "European"),
  ("Europe", "Male", "Asian", "Chinese"),
  ("Europe", "Female", "Asian", "Chinese"),
  ("Europe", "Male", "Black", "African"),
  ("Europe", "Female", "Black", "African"),
  ("Europe", "Male", "White", "European"),
  ("Europe", "Female", "White", "European")
)

代码核心逻辑

import org.apache.hadoop.io.serializer.Serialization
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.types.{StringType, StructField, StructType}

import org.apache.spark.sql.{Dataset, Row, SparkSession}
import org.json4s.NoTypeHints
import org.json4s.DefaultFormats
import org.json4s.jackson.Serialization.writePretty
 定义Node类
//case class Node(title: String, key: String, children: Seq[Node])
/*作者:Matrix70
博客地址:https://blog.csdn.net/qq_52128187?type=blog
时间:20231205*/
object Parent_child_v7_xuqiu {
  def main(args: Array[String]): Unit = {

    val conf = new SparkConf().setAppName("Parent_child_v3").setMaster("local[1]")
    val sc = new SparkContext(conf)
    val spark = SparkSession.builder.appName("Parent_child_v3").getOrCreate()

    import spark.implicits._

    val df1 = sc.textFile("C:\\zzcode\\workplace\\src\\main\\data\\country")

    val schema = StructType(
      Array(
        StructField("Country", StringType, nullable = true),
        StructField("Gender", StringType, nullable = true),
        StructField("Ethnicity", StringType, nullable = true),
        StructField("Race", StringType, nullable = true)
      )
    )

    val rowRDD = df1.map(line => {
      val parts = line.split(",")
      Row(parts(0), parts(1), parts(2), parts(3))
    })

    val df = spark.createDataFrame(rowRDD, schema)

    df.show()
    // 构建节点层级结构并转换为JSON格式
    def toHierarchy(df: Dataset[Row]): String = {
      def buildHierarchy(country: String): Node = {
        val uniqueGenders = df.filter($"Country" === country).select("Gender").distinct().as[String].collect()
        val genderNodes = uniqueGenders.map { gender =>
          val filteredRows = df.filter($"Country" === country && $"Gender" === gender)
          val ethnicityNodes = filteredRows.select("Ethnicity").distinct().as[String].collect().map { ethnicity =>
            val children = filteredRows.filter($"Ethnicity" === ethnicity).select("Race").as[String].collect().map(race => Node(race, s"$country-$gender-$ethnicity-$race", Seq.empty))
            Node(ethnicity, s"$country-$gender-$ethnicity", children)
          }
          Node(gender, s"$country-$gender", ethnicityNodes)
        }
        Node(country, country, genderNodes)
      }

      val uniqueCountries = df.select("Country").distinct().as[String].collect()
      val roots = uniqueCountries.map(buildHierarchy)

      implicit val formats: DefaultFormats.type = DefaultFormats
      writePretty(roots)
    }

    // 调用toHierarchy并打印结果
    val resultJSON = toHierarchy(df)
    println(resultJSON)

    spark.stop()
  }
}

提供给前端的html树结构样例

代码生成结果提供给前端的格式

[
  {
    "title": "USA",
    "key": "USA",
    "children": [
      {
        "title": "Male",
        "key": "USA-Male",
        "children": [
          {
            "title": "Asian",
            "key": "USA-Male-Asian",
            "children": [
              {
                "title": "Chinese",
                "key": "USA-Male-Asian-Chinese",
                "children": []
              }
            ]
          },
          {
            "title": "Black",
            "key": "USA-Male-Black",
            "children": [
              {
                "title": "African",
                "key": "USA-Male-Black-African",
                "children": []
              }
            ]
          },
          {
            "title": "White",
            "key": "USA-Male-White",
            "children": [
              {
                "title": "European",
                "key": "USA-Male-White-European",
                "children": []
              }
            ]
          }
        ]
      },
      {
        "title": "Female",
        "key": "USA-Female",
        "children": [
          {
            "title": "Asian",
            "key": "USA-Female-Asian",
            "children": [
              {
                "title": "Chinese",
                "key": "USA-Female-Asian-Chinese",
                "children": []
              }
            ]
          },
          {
            "title": "Black",
            "key": "USA-Female-Black",
            "children": [
              {
                "title": "African",
                "key": "USA-Female-Black-African",
                "children": []
              }
            ]
          },
          {
            "title": "White",
            "key": "USA-Female-White",
            "children": [
              {
                "title": "European",
                "key": "USA-Female-White-European",
                "children": []
              }
            ]
          }
        ]
      }
    ]
  },
  {
    "title": "Europe",
    "key": "Europe",
    "children": [
      {
        "title": "Male",
        "key": "Europe-Male",
        "children": [
          {
            "title": "Asian",
            "key": "Europe-Male-Asian",
            "children": [
              {
                "title": "Chinese",
                "key": "Europe-Male-Asian-Chinese",
                "children": []
              }
            ]
          },
          {
            "title": "Black",
            "key": "Europe-Male-Black",
            "children": [
              {
                "title": "African",
                "key": "Europe-Male-Black-African",
                "children": []
              }
            ]
          },
          {
            "title": "White",
            "key": "Europe-Male-White",
            "children": [
              {
                "title": "European",
                "key": "Europe-Male-White-European",
                "children": []
              }
            ]
          }
        ]
      },
      {
        "title": "Female",
        "key": "Europe-Female",
        "children": [
          {
            "title": "Asian",
            "key": "Europe-Female-Asian",
            "children": [
              {
                "title": "Chinese",
                "key": "Europe-Female-Asian-Chinese",
                "children": []
              }
            ]
          },
          {
            "title": "Black",
            "key": "Europe-Female-Black",
            "children": [
              {
                "title": "African",
                "key": "Europe-Female-Black-African",
                "children": []
              }
            ]
          },
          {
            "title": "White",
            "key": "Europe-Female-White",
            "children": [
              {
                "title": "European",
                "key": "Europe-Female-White-European",
                "children": []
              }
            ]
          }
        ]
      }
    ]
  }
]
//https://blog.csdn.net/qq_52128187?type=blog

补充html文件

json生成前端界面展示代码,可以保存在本地文件,命名为html即可在浏览器打开查看,就是我上面的层级结构的样子了。

<!DOCTYPE html>
<html>
<head>
  <title>JSON to Tree Example</title>
  <script src="https://d3js.org/d3.v6.min.js"></script>
  <style>
    .node circle {
      fill: #fff;
      stroke: steelblue;
      stroke-width: 1.5px;
    }

    .node text {
      font-size: 12px;
    }
  </style>
</head>
<body>
  <div id="tree-container"></div>

<script>
// JSON字符串
const jsonStr = `{
  "title": "USA",
  "key": "USA",
  "children": [
    {
      "title": "Asian",
      "key": "USA-Asian",
      "children": [
        {
          "title": "Chinese",
          "key": "USA-Asian-Chinese",
          "children": [
            {
              "title": "Beijing",
              "key": "USA-Asian-Chinese-Beijing",
              "children": []
            }
          ]
        }
      ]
    },
    {
      "title": "Black",
      "key": "USA-Black",
      "children": [
        {
          "title": "African",
          "key": "USA-Black-African",
          "children": [
            {
              "title": "Nigeria",
              "key": "USA-Black-African-Nigeria",
              "children": []
            }
          ]
        }
      ]
    },
    {
      "title": "White",
      "key": "USA-White",
      "children": [
        {
          "title": "European",
          "key": "USA-White-European",
          "children": [
            {
              "title": "Italy",
              "key": "USA-White-European-Italy",
              "children": []
            }
          ]
        }
      ]
    }
  ]
}`;

// 解析JSON字符串为树状结构
const data = JSON.parse(jsonStr);

// 创建绘图容器
const svg = d3.select("#tree-container")
  .append("svg")
  .attr("width", 500)
  .attr("height", 500);

// 创建树布局
const treeLayout = d3.tree().size([400, 400]);

// 将数据转换为层级关系
const root = d3.hierarchy(data);

// 计算节点的位置
treeLayout(root);

// 绘制节点和链接
const nodes = root.descendants();
const links = root.links();

const nodeGroup = svg.selectAll(".node")
  .data(nodes)
  .enter()
  .append("g")
  .attr("transform", d => `translate(${d.y}, ${d.x})`);

nodeGroup.append("circle")
  .attr("r", 5)
  .style("fill", "#fff")
  .style("stroke", "steelblue")
  .style("stroke-width", "1.5px");

nodeGroup.append("text")
  .attr("x", 13)
  .attr("y", 4)
  .style("font-size", "12px")
  .text(d => d.data.title);

svg.selectAll(".link")
  .data(links)
  .enter()
  .append("path")
  .attr("class", "link")
  .attr("d", d => {
    return `M${d.source.y},${d.source.x}L${d.target.y},${d.target.x}`;
  })
  .style("fill", "none")
  .style("stroke", "#ccc")
  .style("stroke-width", "1px");
</script>
</body>
</html>

其实我要的结果就是能匹配上数据格式,如下图。前端的同事他们渲染后,基本就是这个样子

参考文章获连接:

Ant Design Vue — An enterprise-class UI components based on Ant Design and Vue.js,这个网页是树形控件的结构,给我提供一个基本构建思路吧

ok!!!

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

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

相关文章

flask web学习之flask与http(一)

文章目录 一、请求响应循环二、HTTP请求1. 请求报文2. request对象3. 在flask中处理请求3.1 路由匹配3.2 设置监听的http方法3.3 URL处理 三、请求钩子 一、请求响应循环 每一个web应用都包含这种处理方式&#xff0c;请求-响应循环&#xff1a;客户端发出请求&#xff0c;服务…

Linux【缓冲区】

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析&#xff08;3&#xff09; 目录 &#x1f449;&#x1f3fb;缓冲区是什么&#xff1f;为…

23、pytest通过skip跳过测试用例

官方实例 # content of test_skip.py import pytest import syspytest.mark.skip(reason"no way of currently testing this") def test_the_unknown():passdef valid_config():return Falsedef test_function():if not valid_config():pytest.skip("unsupport…

毕业论文及各种办公文件word页码的设置大全

当我们在写论文或者报告的时候&#xff0c;经常需要我们给文档设置页码&#xff0c;用于页码统计&#xff0c;也方便后期的查阅和阅读&#xff0c;但是经常遇到特殊的要求或者情况&#xff0c;比如删除了某个页的页码&#xff0c;那么整个文档目录的页码就会全部被删除&#xf…

Retrofit的转换器

一、前言 1.为什么要使用Retrofit转换器 在我们接受到服务器的响应后&#xff0c;目前无论是OkHttp还是Retrofit都只能接收到String字符串类型的数据&#xff0c;在实际开发中&#xff0c;我们经常需要对字符串进行解析将其转变为一个JavaBean对象&#xff0c;比如服务器响应…

【计算机网络笔记】物理层——信道与信道容量

系列文章目录 什么是计算机网络&#xff1f; 什么是网络协议&#xff1f; 计算机网络的结构 数据交换之电路交换 数据交换之报文交换和分组交换 分组交换 vs 电路交换 计算机网络性能&#xff08;1&#xff09;——速率、带宽、延迟 计算机网络性能&#xff08;2&#xff09;…

静态VS动态代理IP:对比静态和动态代理IP的区别,如何选择?

在现代网络环境中&#xff0c;代理IP的作用不容小觑。它作为一种有效的网络工具&#xff0c;帮助用户在网上保持匿名性&#xff0c;同时还能绕过地理限制、提高安全性和增强数据收集的能力 在众多类型的代理IP中&#xff0c;静态和动态代理IP是最常见的两种形式。下面我们深入…

网络模拟与网络仿真

目录 一、概念界定 二、模拟&#xff08;simulation&#xff09;与仿真&#xff08;emulation&#xff09; 2.1 模拟&#xff08;simulation&#xff09; 2.2 仿真&#xff08;emulation&#xff09; 2.3 区分 三、网络模拟与网络仿真 3.1 网络模拟 3.2 网络仿真 3.…

properties出现中文乱码解决方法(万能)

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 在使用Properties类的时候,中文出现乱码 如图所示: 正常思维来讲,估计是中文编码有问题,于是我将其改为UTF-8的编码方式 通过下方的改动: 可到了这一步,中文还是乱码(这一步改成功的网友可自动立场,没改成功的网…

持续集成交付CICD:Sonarqube 扫描本地项目(关联Gitlab项目与Jenkins流水线)

目录 一、实验 1.Java项目扫描 2.视图徽章 3.版本管理 一、实验 1.Java项目扫描 &#xff08;1&#xff09;指定项目信息关联的首页为GitLab项目&#xff0c;持续集成为Jenkins流水线 &#xff08;2&#xff09;命令行 sonar-scanner -Dsonar.host.urlhttp://192.168.20…

【算法】算法题-20231206

这里写目录标题 一、非自身以外数字的乘积二、最大数三、奇数排序 一、非自身以外数字的乘积 给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀…

在eclipse中安装python插件:PyDev

在eclipse中安装插件PyDev&#xff0c;就可以在eclipse中开发python了。 PyDev的官网&#xff1a;https://www.pydev.org/ 不过可以直接在eclipse中用Marketplace安装&#xff08;备注&#xff1a;有可能一次安装不成功&#xff0c;是因为下载太慢了&#xff0c;多试几次&…

极简模式,助力宏观数据监控

随着UWA GOT Online采样的参数越来越多样化&#xff0c;为了提升开发者的使用体验&#xff0c;我们最新推出了三种预设数据采集方案&#xff1a;极简模式、CPU模式、内存模式。该更新旨在降低多数据采集对数据准确性的干扰&#xff0c;同时也为大家提供更精准且有针对性的数据指…

『亚马逊云科技产品测评』活动征文|基于亚马逊EC2云服务器安装Bolo开源博客

授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 亚马逊EC2云服务器&#xff08;Elastic Compute Cloud&#xff09;是亚马…

微软NativeApi-NtQuerySystemInformation

微软有一个比较实用的Native接口&#xff1a;NtQuerySystemInformation&#xff0c;具体可以参考微软msdn官方文档&#xff1a;NtQuerySystemInformation&#xff0c; 是一个系统函数&#xff0c;用于收集特定于所提供的指定种类的系统信息。ProcessHacker等工具使用NtQuerySys…

HarmonyOS学习--TypeScript语言学习(二)

本章目录如下&#xff1a; 一、基础类型 二、运算符 三、变量声明 四、类型断言 五、类型推断 TypeScript支持一些基础的数据类型&#xff0c;如布尔型、数组、字符串等&#xff0c;下文举例几个较为常用的数据类型&#xff0c;我们来了解下他们的基本使用。 关于let 我们…

python爬虫混肴DES案例:某影视大数据平台

声明&#xff1a; 该文章为学习使用&#xff0c;严禁用于商业用途和非法用途&#xff0c;违者后果自负&#xff0c;由此产生的一切后果均与作者无关 一、找出需要加密的参数 js运行atob(‘aHR0cHM6Ly93d3cuZW5kYXRhLmNvbS5jbi9Cb3hPZmZpY2UvQk8vTW9udGgvb25lTW9udGguaHRtbA’…

模拟电路学习笔记(一)之芯片篇(持续更新)

模拟电路学习笔记&#xff08;一&#xff09;之芯片篇&#xff08;持续更新&#xff09; 1.CD4047BE芯片 CD4047是一种包含高电压的多谐振荡器&#xff0c;该器件的操作可以在两种模式下完成&#xff0c;分别是单稳态和非稳态。CD4047需要一个外部电阻器和电容器来决定单稳态…

FL Studio中如何录音的技巧,让你的声音更加出众哦!

​ Hey小伙伴们&#xff01;今天我要和大家分享一下在FL Studio中如何录音的技巧&#xff0c;让你的声音更加出众哦&#xff01; 编曲软件FL Studio 即“Fruity Loops Studio ”&#xff0c;也就是众所熟知的水果软件&#xff0c; 全能音乐制作环境或数字音频工作站&#xff0…

一位半加法器,一位全加器,四位全加器

我们这里的加法器只考虑一位的情况。 当我们两个一位相加的话&#xff0c;那么就有两个输入&#xff0c;两个输出&#xff0c;两个输入很好理解&#xff0c;就是两个个位上的数字&#xff0c;0或者是1&#xff0c;那么为什么需要有有个输出呢&#xff1f;难道不是输出一个数就…