【Ne4j图数据库入门笔记2】数据导入详解

2.1 导入 CSV 文件

Cypher中 LOAD CSV 的命令允许我们指定文件路径、标头与否、不同的值分隔符以及 Cypher 语句,用于我们如何在图形中对表格数据进行建模。

CSV 是逗号分隔值的文件,通常在 Excel 或其他电子表格工具中查看。可以有其他类型的值作为分隔符,但最标准的是逗号。如今,许多系统和流程已经将其数据转换为 CSV 格式,以便将文件输出到其他系统、人性化报告和其他需求。它是一种标准文件格式。

2.1.1 导入 CSV 文件的方法

有几种不同的方法可以将 CSV 数据导入 Neo4j,每种方法都有不同的标准和功能。您选择的选项取决于数据集大小,以及您对各种工具的熟悉程度。

让我们看看 Neo4j 读取和导入 CSV 文件的一些方法。

  1. LOAD CSV命令:此Cypher命令是一个很好的起点,可以处理中小型数据集(最多 1000 万条记录)。适用于任何设置,包括 AuraDB。
  2. neo4j-admin database import 命令:命令行工具可用于直接加载大型数据集。适用于 Neo4j Desktop、Neo4j EE Docker 镜像和本地安装。
  3. Neo4j ETL 工具:Neo4j Labs 项目。有关更多详细信息和文档,请访问 Neo4j ETL 工具页面。
  4. Kettle 导入工具:映射和执行数据处理流的步骤,适用于非常大的数据集,尤其是在您已经熟悉使用此工具的情况下。适用于任何设置,包括 AuraDB。

在下面的部分中,您可以找到 LOAD CSV Cypher 命令和 neo4j-admin database import 命令的简要视图、它们如何操作以及如何开始使用一般用例。对于将任何类型的数据导入到任何系统,数据质量也可能是一个问题,因此本节将介绍其中的一些潜在困难和克服这些困难的方法。

2.1.2 使用LOAD CSV命令导入

LOAD CSV 子句是 Cypher 查询语言的一部分。有关该 LOAD CSV 子句的更多信息,请参阅 LOAD CSV → Cypher 手册。它适用范围广泛。 LOAD CSV 不仅仅是一种基本的数据引入机制。它在一次操作中执行多个操作:

  • 支持从 URI 加载/引入 CSV 数据。
  • 将输入数据直接映射到复杂的图形/域结构中。
  • 处理数据转换。
  • 支持复杂的计算。
  • 创建或合并实体、关系和结构。

为了更好地控制,您可以使用 Cypher Shell 而不是在 Neo4j 浏览器中运行 LOAD CSV 命令。关于Cypher Shell的更多信息,请参见《Cypher Shell→操作手册》。

2.1.2.1 读取 CSV 文件

LOAD CSV 可以处理本地和远程文件,并且每个文件都有一些语法。这可能很容易错过并最终导致访问错误,因此此处澄清了规则。

本地文件需要在文件名前加上前缀 file:///来加载。

由于 AuraDB 是基于云的,因此这种本地文件方法不适用于 AuraDB。

出于安全原因,默认情况下,本地文件只能从 Neo4j 导入目录中读取,根据您的操作系统而有所不同。每个操作系统的文件位置都列在我们的 Neo4j 操作手册→文件位置中。建议将文件放在 Neo4j 的导入目录中,因为它可以保证环境的安全。但是,如果您需要访问其他位置的文件,您可以在我们的 Cypher 手册→ LOAD CSV 简介中找到要更改的设置。

Neo4j 发行版Default file location
Linux / macOS / Docker<NEO4J_HOME>/import
Windows<NEO4J_HOME>/import
Debian / RPM/var/lib/neo4j/import
Neo4j DesktopFrom the Open dropdown menu of your active Neo4j DBMS, select Terminal, and run cd import.
//Example 1 - file directly placed in import directory (import/data.csv)   
LOAD CSV FROM "file:///data.csv"//Example 2 - file placed in subdirectory within import directory (import/northwind/customers.csv)
LOAD CSV FROM "file:///northwind/customers.csv"

Web 托管的文件可以直接使用其 URL 进行引用,例如 https://host/path/data.csv。但是,必须设置权限,以便外部源可以读取文件。要从本地文件系统中读取文件,您需要检查配置 dbms.security.allow_csv_import_from_file_urls 是否设置为 true 。有关与联机文件导入相关的访问的详细信息,请参阅此知识库文章。但请记住,在 Neo4j v5 中,配置设置已被重命名,dbms.directories.import被更改为 server.directories.import .

//Example 1 - website
LOAD CSV FROM 'https://data.neo4j.com/northwind/customers.csv' //Example 2 - Google
LOAD CSV WITH HEADERS FROM 'https://docs.google.com/spreadsheets/d/<yourFilePath>/export?format=csv'
2.1.2.2 有关 LOAD CSV 的重要提示

需要注意:

  • CSV 文件中的所有数据都以字符串形式读取,因此需要使用 toInteger()toFloat()split() 或类似的函数来转换值。
  • 检查您的 Cypher import 语句是否有拼写错误。标签、属性名称、关系类型和变量区分大小写。
  • 数据越干净,加载越容易。尝试在加载之前处理复杂的清理/操作。
2.1.2.3 使用 LOAD CSV 转换数据值

Cypher 具有一些清理和转换功能,可帮助清理数据。这些对于处理缺失数据或将字段拆分为图形的多个值非常有用。

首先,请记住 Neo4j 不存储 null 值。可以跳过 CSV 文件中的 null 或空字段,或将其替换为 LOAD CSV中的默认值。

假设你有这个companies.csv文件:

Id,Name,Location,Email,BusinessType 
1,Neo4j,San Mateo,contact@neo4j.com,P
2,AAA,,info@aaa.com,
3,BBB,Chicago,,G

线上数据文件地址:https://docs.google.com/spreadsheets/d/e/2PACX-1vSBOKZ0dfP1QJD7YzaRH7o5SvFxFlmMsnvaXkNF4_t0gGnemenEHjBg7y3akOmUZIGmMryNlrlrwnfK/pub?output=csv

以下是导入此数据的一些示例。

// 跳过空值数据
LOAD CSV WITH HEADERS FROM 'file:///companies.csv' AS row  
WITH row WHERE row.Id IS NOT NULL
MERGE (c:Company {companyId: row.Id});// clear data
MATCH (n:Company) DELETE n;// 为空值设置默认值
LOAD CSV WITH HEADERS FROM 'file:///companies.csv' AS row
MERGE (c:Company {companyId: row.Id, hqLocation: coalesce(row.Location, "Unknown")})// clear data
MATCH (n:Company) DELETE n;// 将空字符串转为null值(不存储)
LOAD CSV WITH HEADERS FROM 'file:///companies.csv' AS row
MERGE (c:Company {companyId: row.Id})
SET c.emailAddress = CASE trim(row.Email) WHEN "" THEN null ELSE row.Email END

接下来,如果 CSV 中有一个字段是要拆分的项目列表,则可以使用 Cypher split() 函数分隔单元格中的数组。

假设你有这个employees.csv文件:

Id,Name,Skills,Email
1,Joe Smith,Cypher:Java:JavaScript,joe@neo4j.com
2,Mary Jones,Java,mary@neo4j.com
3,Trevor Scott,Java:JavaScript,trevor@neo4j.com

线上文件地址:https://docs.google.com/spreadsheets/d/e/2PACX-1vT3T-aocniTs91ZI12pc5VUAJo0JK9kqzf3So7XV9EAOVdcYMmbKyS1bSRYdPqNu_AdI-AzO2Rfxu5v/pub?output=csv

导入数据

LOAD CSV WITH HEADERS FROM 'file:///employees.csv' AS row    
MERGE (e:Employee {employeeId: row.Id, email: row.Email})
WITH e, row
UNWIND split(row.Skills, ':') AS skill
MERGE (s:Skill {name: skill})
MERGE (e)-[r:HAS_EXPERIENCE]->(s)// 查询
match (e:Employee)-[r:HAS_EXPERIENCE]->(s:Skill) return e,r,s

当我们检查空值或空字符串时,条件转换可以通过 CASE 来实现。

// clear data
MATCH (n:Company) DELETE n;//set businessType property based on shortened value in CSV  
LOAD CSV WITH HEADERS FROM 'file:///companies.csv' AS row
WITH row WHERE row.Id IS NOT NULL
WITH row,
(CASE row.BusinessTypeWHEN 'P' THEN 'Public'WHEN 'R' THEN 'Private'WHEN 'G' THEN 'Government'ELSE 'Other' END) AS type
MERGE (c:Company {companyId: row.Id, hqLocation: coalesce(row.Location, "Unknown")})
SET c.emailAddress = CASE trim(row.Email) WHEN "" THEN null ELSE row.Email END
SET c.businessType = type
RETURN *
2.1.2.4 优化 LOAD CSV 以提高性能

通常,有一些方法可以提高数据加载期间的性能,这在处理大量数据或复杂加载时特别有用。

为了改进在图形中插入或更新唯一实体(使用 MERGE 或 MATCH 更新),您可以为计划合并或匹配的每个标签和属性创建声明的索引和约束。

为了获得最佳性能,请 MATCHMERGE 在具有索引主键属性的单个标签上。

假设您使用前面的 companies.csv 文件,现在您有一个包含人员及其工作公司的people.csv文件:

employeeId,Name,Company
1,Bob Smith,1
2,Joe Jones,3
3,Susan Scott,2
4,Karen White,1

线上文件地址:https://docs.google.com/spreadsheets/d/e/2PACX-1vSz77w7NFnLy8eelAxAhr10L4O9p-5jtQ17uFcbNvYesGO-12wuBo0EbvgMCxC8aWcFHPp8_JDZgryp/pub?output=csv

还应将节点和关系的创建分开处理。例如,可以用以下方式代替

MERGE (e:Employee {employeeId: row.employeeId})
MERGE (c:Company {companyId: row.companyId})
MERGE (e)-[r:WORKS_FOR]->(c) 

可以这样写:

// clear data
MATCH (n)
DETACH DELETE n;// 加载Employee节点
LOAD CSV WITH HEADERS FROM 'file:///people.csv' AS row     
MERGE (e:Employee {employeeId: row.employeeId, name: row.Name})
RETURN count(e);// 加载Company节点
LOAD CSV WITH HEADERS FROM 'file:///companies.csv' AS row
WITH row WHERE row.Id IS NOT NULL
WITH row,
(CASE row.BusinessTypeWHEN 'P' THEN 'Public'WHEN 'R' THEN 'Private'WHEN 'G' THEN 'Government'ELSE 'Other' END) AS type
MERGE (c:Company {companyId: row.Id, hqLocation: coalesce(row.Location, "Unknown")})
SET c.emailAddress = CASE trim(row.Email) WHEN "" THEN null ELSE row.Email END
SET c.businessType = type
RETURN count(c);// 创建关系
LOAD CSV WITH HEADERS FROM 'file:///people.csv' AS row
MATCH (e:Employee {employeeId: row.employeeId})
MATCH (c:Company {companyId: row.Company})
MERGE (e)-[:WORKS_FOR]->(c)
RETURN *;

这样,load一次只执行一段导入,并且可以快速有效地处理大量数据,从而减少繁重的处理。

当加载的数据量过大而无法放入内存时,可以使用几种不同的方法来应对数据加载期间内存不足的问题。

  1. 使用CALL { ... } IN TRANSACTIONS将导入批量分段进行。。

    可以在 LOAD CSV 子句之后添加此子查询,以告诉 Cypher 在清除内存和事务状态之前只处理这么多行的文件。有关详细信息,请参阅 Cypher Manual → Subqueries。

    LOAD CSV FROM 'file:///people.csv' AS line
    CALL {WITH lineMATCH (e:Employee {id: line[0]})CREATE (e)-[:REL {prop: line[1]}]->(e)
    } IN TRANSACTIONS OF 100000 ROWS;
    
  2. 避开 Eager 操作

    某些语句拉取的行数超出了必要的行数,从而预先添加了额外的处理。为了避免这种情况,您可以对查询运行 PROFILE ,以查看它们是否使用 Eager 加载,然后修改查询或在同一文件上运行多次,这样就不会出现这种情况了。有关 Eager操作符的更多信息 ,请详细参见 Cypher manual → Execution plan operators in detail

  3. 调整堆和内存上的数据库配置,以避免页面错误。

    为了帮助处理大量事务,您可以增加数据库的某些配置设置并重新启动实例以使其生效。通常,每 2 GB 堆可以在单个事务中创建或更新 100 万条记录。在 neo4j.conf

    • server.memory.heap.initial_sizeserver.memory.heap.max_size : 设置为至少 4G。
    • server.memory.pagecache.size :理想情况下,值足够大,可以将整个数据库保留在内存中。

2.1.3 neo4j-admin database import 命令

命令详情:https://neo4j.com/docs/operations-manual/current/tools/neo4j-admin/neo4j-admin-import/

LOAD CSV 非常适合导入中小型数据集(最多 1000 万条记录)。对于大于此值的数据集,可以使用以下 neo4j-admin database import 命令。这允许您通过指定节点文件和关系文件将 CSV 数据导入未使用的数据库。

neo4j-admin database import 命令只能用于初始图形填充。

假设您想将订单数据通过 neo4j-admin database import导入 到 Neo4j 实例中。请注意,以下某些 CSV 文件包含标头,而某些文件具有单独的头文件。如果要执行导入,请将它们放在 Neo4j 实例的导入文件夹中。

customers.csv

customerId:ID(Customer), name
23, Delicatessen Inc
42, Delicious Bakery 

products.csv( 有一个产品节点,具有 ID 为 11,名称为 Chocolate,价格为 10 的产品,并且它属于 Product 和 Food 这两个标签 )

productId:ID(Product), name, price, :LABEL 
11,Chocolate,10,Product;Food

orders_header.csv

orderId:ID(Order),date,total,customerId:IGNORE

customer_orders_header.csv(:START_ID(Customer) 表示关系起点为 Customer,:END_ID(Order) 表示关系终点为 Order,date:IGNORE 和 total:IGNORE 则表示在创建关系时忽略日期和总价这两个属性 )

:END_ID(Order),date:IGNORE,total:IGNORE,:START_ID(Customer)

orders1.csv

1041,2020-05-10,130,23

orders2.csv

1042,2020-05-12,20,42

order_details.csv

:START_ID(Order),amount,price,:END_ID(Product)
1041,13,130,11
1042,2,20,11

neo4j-admin database import 命令有两种模式:

  • full — 用于最初将数据导入不存在的空数据库。
  • incremental — 用于以增量方式将数据导入现有数据库。

该工具位于 <neo4j-instance-location>/bin/neo4j-admin 中 ,您可以在终端窗口中运行该命令,在该窗口中导航到 Neo4j 实例的import目录。

以下是在 Neo4j 5.x 中导入上述 CSV 文件的示例。必须指定数据库的名称。在本例中,我们指定订单。

bin/neo4j-admin database import full--nodes=Customer=import/customers.csv--nodes=import/products.csv --nodes=Order=import/orders_header.csv, import/orders1.csv, import/orders2.csv--relationships=CONTAINS=import/order_details.csv--relationships=ORDERED=import/customer_orders_header.csv, import/orders1.csv, import/orders2.csv--trim-strings=true orders

您必须在一行中指定此脚本的参数。此处显示换行符是为了便于阅读。

运行该命令时,它将导入数据并将其提供给数据库。neo4j-admin 数据库导入命令不会创建新数据库。

重复的--nodes--relationships 参数是同一实体的多个(可能拆分)CSV 文件的组,即具有相同的列结构。

每个组的所有文件都被视为可以串联为一个大文件。组的第一个文件或单独的单行文件中的标题行是必需的。将标头放在单独的文件中比将其放在数 GB 的文本文件中更容易处理和编辑。还支持压缩文件。

  • --id-type=string: 所有 :ID 列都包含字母数字值(针对纯数字 ID 进行了优化)。
  • customers.csv 直接作为带有 :Customer 标签的节点导入,属性直接从文件中提取。
  • Product 节点遵循相同的模式,节点标签取自文件中的:LABEL列。
  • Order节点取自三个文件,一个标头文件和两个内容文件。
  • order_details.csv中创建类型为:CONTAINS的行项目关系,通过 ID 将订单与所含产品联系起来。
  • 再次使用订单 CSV 文件将订单与客户连接起来,但这次使用了不同的标题,即:IGNORE是不相关的列。

列名用于节点和关系的属性名称。特定列上有特定标记:

  • name:ID:全局 ID 列,用于在以后重新连接时查找节点。
    • 如果省略属性名称,则不会存储它(临时),这就是所指的 --id-type 。
    • 如果跨实体有重复的 ID,则必须在括号中提供实体 (id-group),例如 :ID(Order) 。
    • 如果您的 ID 是全局唯一的,则可以将其关闭。
  • :LABEL:节点的标签列。多个标签可以通过分隔符分隔。
  • :START_ID:END_ID:引用节点 ID 的关系文件列。对于 id-groups,请使用 :END_ID(Order):START_ID(Customer) 表示关系起点为 Customer,:END_ID(Order) 表示关系终点为 Order
  • :TYPE:列指定关系类型。
  • 所有其他列都被视为属性,但如果为空或用 :IGNORE批注,则跳过。date:IGNORE 和 total:IGNORE 则表示在创建关系时忽略日期和总价这两个属性。
  • 可以通过在名称后加上 :INT:BOOLEAN 等指示符来进行类型转换。

2.1.4 CSV 数据质量

常见陷阱

  • 标题与数据不一致(缺少或过多列、标题中的分隔符不同)。

    验证标头是否与文件中的数据匹配。在此阶段调整格式、分隔符、列等将在以后节省大量时间。

  • 整个文件中多余或缺少引号。

    非引号文本中间的独立双引号或单引号或引号文本中的非转义引号可能会导致读取文件以进行加载时出现问题。最好转义或删除杂散引号。正确转义的文档在 Cypher 样式指南中。

  • 文件中的特殊字符或换行符。

    在处理文件中的特殊字符时,应确保为其加上引号或将其删除。对于有引号或无引号字段中的换行符,要么为其加上引号,要么将其删除。

  • 不一致的换行符。

    计算机不能很好地处理的一件事是数据不一致。确保换行符始终保持一致。我们建议选择 Unix 样式以兼容 Linux 系统(导入工具的通用格式)。

  • 二进制零、文件开头的 BOM 字节顺序标记(2 个 UTF-8 字节)或其他非文本字符。

    任何不寻常的字符或特定于工具的格式有时隐藏在应用程序工具中,但在基本编辑器中很容易显现。如果您在文件中遇到这些类型的字符,最好将它们完全删除。

如上所述,某些应用程序有特殊的格式设置,使文档看起来更美观,但这些隐藏的额外代码是普通文件阅读器和脚本无法处理的。还有一些时候,对于数据量很大的文件,很难发现微小的语法变化或进行大范围的调整。

为了处理这些类型的情况或常规数据清理,有许多工具可以帮助您检查和验证 CSV 数据文件。

基本工具(如 hexdump、vi、emacs、UltraEdit 和 Notepad++)适用于处理用于编辑和操作文件的基于快捷方式的命令。但是,还有其他更有效或用户友好的选项可用于帮助数据清理和格式化。

  • Cypher:Cypher 看到的就是将要导入的内容,因此您可以利用它来发挥自己的优势。在不创建图形结构的情况下使用 LOAD CSV 仅输出样本、计数或分布,以便可以检测不正确的标题列计数、分隔符、引号、转义或标题名称拼写。

    // assert correct line count
    LOAD CSV FROM "file-url" AS line  
    RETURN count(*);// check first 5 line-sample with header-mapping
    LOAD CSV WITH HEADERS FROM "file-url" AS line
    RETURN line
    LIMIT 5;
    
  • CSVKit:一组 Python 工具,可为您的 CSV 文件提供统计信息 (csvstat)、搜索 (csvgrep) 等。

  • CSVLint:用于验证 CSV 文件的在线服务。您可以上传文件或提供 URL 来加载它。

  • Papa Parse:一个用于 CSV 解析的综合 Javascript 库,允许您流式传输 CSV 数据并提供良好的、人类可读的问题错误报告。

2.2 通过REST API导入JSON数据

https://neo4j.com/docs/getting-started/data-import/json-rest-api-import/

我们可以将大量基于 JSON 的 Web API 导入到 Neo4j 中,并且可以使用其中一个LOAD JSON程序从这些 API 中检索数据并将其转换为可供 Cypher使用的映射值。

APOC 用户指南提供了一个工作示例,展示了如何将数据从 StackOverflow 导入 Neo4j。

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

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

相关文章

spring.factories中配置ApplicationContextInitializer实现类却不起作用

自定义了一个ApplicationContextInitializer的实现类如下 public class MyApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {Overridepublic void initialize(ConfigurableApplicationContext applicationCon…

Vue3 Vite配置环境变量

Vue3 Vite配置环境变量 相关文档配置.env文件vite.config.jspackage.json 使用 相关文档 Vite 官方中文文档&#xff1a;https://cn.vitejs.dev/环境变量和模式&#xff1a;https://cn.vitejs.dev/guide/env-and-mode.html#env-file在配置中使用环境变量&#xff1a;https://c…

SCADA系统通过巨控GRM模块实现OPC协议远程监控PLC

SCADA系统和PLC不在同一个地方&#xff0c;需要远程监控和控制PLC&#xff0c;可以通过巨控GRM模块来实现&#xff0c;通过OPC协议转巨控服务器远程读写PLC寄存器&#xff0c;从而完成远程监控PLC。 要实现SCAKDA系统远程监控PLC&#xff0c;关键是要实现SKADA能通过互联网访问…

vue3+leaflet开发地图入门教程(超级详细)

vue3leaflet开发地图01 1.离线地图下载 ​ 离线地图下载器有很多&#xff0c;网络上也很多文档&#xff0c;这里不再详细说明&#xff0c;根据项目要求下载对应的瓦片地图就好 2.leaflet官网及地图加载 ​ Leaflet - 一个交互式地图 JavaScript 库 (leafletjs.cn) ​ 官网…

Java动态代理与Spring AOP中的Cglib动态代理详解

在Java编程中&#xff0c;动态代理是一种在运行时动态创建代理类及其对象的技术。通过动态代理&#xff0c;我们可以在不修改原有类代码的情况下&#xff0c;为这些类添加新的行为或功能。Java提供了两种主要的动态代理机制&#xff1a;基于接口的Java动态代理和基于类的Cglib动…

密钥派生算法介绍 及 PBKDF2(过时)<Bcrypt(开始淘汰)<Scrypt< Argon2(含Argon2d、Argon2i、Argon2id)简介

密钥派生算法介绍 https://blog.csdn.net/xcxhzjl/article/details/127297263 一、定义 密钥派生函数(Key Derivation Function)就是从一个密码产生出一个或多个密钥&#xff0c;具体就是从一个master key&#xff0c;password或者passphrase派生出一个或多个密钥&#xff0…

HCIP-Datacom-ARST必选题库_23_SNMP【1道题】

一、单选 1.某中型规模园区网络通过SNMP协议管理网络,该园区对于网络安SNMP哪个版本进行管理? 所有版本均可以实现 BSNMPV1 SNMPV2C SNMPV3

都2024 年了,可以卸载的VS Code 插件

在 VS Code 中&#xff0c;庞大的插件市场提供了丰富多样的扩展功能&#xff0c;以增强编码体验和效率。然而&#xff0c;如果你安装了很多插件&#xff0c;就可能会导致&#xff1a; 性能下降&#xff1a;过多的插件可能导致 VS Code 的启动速度变慢&#xff0c;特别是在启动或…

[2021最新]大数据平台CDH存储组件kudu之启用HA高可用(添加多个master)

今天在做kudu高可用的时候没有参考官网&#xff0c;直接按照常规方式&#xff08;添加角色—>编辑属性—>启动&#xff09;结果发现报错&#xff1f;然后参考了一下文档之后发现这玩意儿还有点玄学&#xff0c;做一下记录。 1.添加两个master。kudu master有leader和foll…

薪酬调整流程:规范流程并确保公平合理

薪酬调整是企业人力资源管理中不可或缺的一环&#xff0c;它直接关系到员工的切身利益和企业的发展。为了确保薪酬调整的公平性和合理性&#xff0c;制定一套规范的薪酬调整流程至关重要。本文将详细阐述薪酬调整流程的各个环节&#xff0c;以及如何确保流程的合理性和公平性。…

用云手机运营TikTok有什么好处?

在数字化浪潮的推动下&#xff0c;社交媒体平台正重塑商业推广与品牌建设的面貌。TikTok&#xff0c;这款全球热门的短视频应用&#xff0c;已经吸引了亿万用户的瞩目。对于出海电商和品牌推广而言&#xff0c;借助云手机运营TikTok&#xff0c;能够解锁更多潜在可能&#xff0…

【Linux开发 第十二篇】搭建JavaEE环境

搭建开发环境 搭建javaEE环境 搭建javaEE环境 在Linux下开发JavaEE需要安装软件包&#xff1a; 安装jdk 安装步骤&#xff1a; 在opt目录下创建jdk目录通过xftp上床到jdk目录中进入到jdk目录中&#xff0c;解压jdk压缩包在/usr/local下创建java目录将解压完成的jdk文件移动…

时间搜索

时间搜索 vue2antd <a-form-item label"订单开始时间:"><a-range-picker v-model"date" valueFormat"YYYY-MM-DD" change"onChange" /></a-form-item> onChange (date) {if (date.length > 0) {this.queryParam.…

li 与 li 之间有看不见的空白间隔是什么原因引起的?如何解决?

浏览器会把inline内联元素间的空白字符&#xff08;空格、换行、Tab等&#xff09;渲染成一个空格。 为了美观&#xff0c;通常是一个放在一行&#xff0c;这导致换行后产生换行字符&#xff0c;它变成一个空格&#xff0c;占用了一个字符的宽度。 解决办法&#xff1a; &…

【MySQL | 第六篇】数据库三大范式

文章目录 6.数据库设计三大范式6.1第一范式6.2第二范式6.3第三范式6.4反范式设计 6.数据库设计三大范式 6.1第一范式 第一范式&#xff08;1NF&#xff09;&#xff1a;确保每列的原子性(强调的是列的原子性&#xff0c;即列不能够再分成其他几列)。实际上&#xff0c;第一范式…

MATLAB初学者入门(10)—— 粒子群算法

粒子群优化&#xff08;Particle Swarm Optimization, PSO&#xff09;是一种基于群体协作的优化技术&#xff0c;它由社会行为模型&#xff08;如鸟群觅食行为&#xff09;启发而来。PSO 通过模拟一群粒子&#xff08;候选解&#xff09;在解空间中的移动来寻找最优解。每个粒…

react学习(一)之初始化一个react项目

React 是一个用于构建用户界面&#xff08;UI&#xff09;的 JavaScript 库&#xff0c;用户界面由按钮、文本和图像等小单元内容构建而成。React 帮助你把它们组合成可重用、可嵌套的 组件。从 web 端网站到移动端应用&#xff0c;屏幕上的所有内容都可以被分解成组件&#xf…

在React Router 6中使用useRouteLoaderData钩子获取自定义路由信息

在 React Router 6 中怎么像vueRouter一样&#xff0c;可以在配置路由的时候&#xff0c;定义路由的元信息(附加信息)&#xff1f;答案是可以的。稍有些复杂。核心是通过为每个路由定义了一个 loader 函数,用于返回自定义的路由信息&#xff0c;然后通过useRouteLoaderData 钩子…

Java使用百度翻译接口开发app

到网站&#xff1a;百度翻译开放平台下载Java版本的demo 使用demo中的三个文件&#xff0c;main不用 默认返回的result内容是这样的: {"from":"en","to":"zh","trans_result":[{"src":"Sure! Heres a sh…

虚拟机扩容方法

概述 我的虚拟机开始的内存是40G,接下来要扩成60GB 扩容步骤 步骤1 步骤2 步骤3 修改扩容后的磁盘大小&#xff0c;修改后的值只可以比原来的大&#xff0c;修改完成后点击扩展&#xff0c;等待扩展完成 步骤4 虽然外面扩展成功&#xff0c;但是新增的磁盘空间虚拟机内部还…