Neo4j随笔

1、图数据库Neo4j介绍

1.1、什么时图数据库(graph database)

当事物存在十分复杂的关系网,传统数据库则很难处理关系运算,图数据库就十分适用于处理庞大的复杂关系网,因此图数据库应运而生。

图数据库是基于图论实现的一种nosql数据库,其数据存储结构和数据查询方式都是以图论为基础的,图数据库主要用于存储更多的连接数据。

图论[Graph Theory]是数学的一个分支。它以图为研究对象,图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。

1.2、什么是Neo4j

neo4j是开源的nosql图形数据库,使用scala和java语言,2007年开始发布

1.3、Neo4j数据模型

图论基础

图是一组节点和连接这些节点的关系,图形以属性的形式将数据存储在节点和关系中,属性是用于表示数据的键值对。在图论中,我们可以用圆圈表示一个节点,节点之间的关系用一个箭头标记表示。

属性图模型

属性图模型规则

  • 表示节点,关系和属性中的数据
  • 节点和关系都包含属性
  • 关系连接节点
  • 属性是键值对
  • 节点用圆圈表示,关系用方向键表示
  • 关系具有方向:单向和双向
  • 每个关系包含“开始节点”或“从节点”和“到节点”或“结束节点”

在属性图数据模型中,关系应该是定向的。如果我们尝试创建没有方向的关系,那么它将抛出错误消息。在Neo4j中,关系也应用是有方向性的。如果我们尝试创建没有方向的关系,那么Neo4j会抛出一个错误小徐,“关系应该是方向性的”。

Neo4j图数据库将其所有数据存储在节点和关系中,我们不需要任何额外的RDBMS数据库或Nosql数据库来存储Neo4j数据库数据,它以图的形式存储数据。Neo4j使用本机GPE(图形处理引擎)来使用它的本机图存储格式。

1.4、Neo4j的构建元素

  • 节点

    节点(Node)是图数据库中的一个基本元素,用来表示一个实体记录,就像关系数据库中的一条记录一样。在Neo4j中节点可以包含多个属性(Property)和多个标签(Label)

    • 节点是主要的数据元素
    • 节点通过关系连接到其他节点
    • 节点可以具有一个或多个属性(即:存储为键/值对的属性)
    • 节点有一个或多个标签,用于描述其在图表中的作用
  • 属性

    属性(Property)是用于描述图节点和关系的键值对。其中Key是一个字符串,值可以通过任何Neo4j数据类型来表示

    • 属性是命名值,其中名称(或键)是字符串
    • 属性可以被索引或约束
    • 可以从多个属性创建符合索引
  • 关系

    关系(Relationship)同样是图数据库的基本元素。当数据库中已经存在节点后,需要将节点连接起来构成图。关系就是用来连接两个节点,关系也称为图论的边(Edge),其始端和末端都必须是节点,关系不能指向空也不能从空发起。关系和节点一样可以包含多个属性,但关系只能有一个类型(Type)

    • 关系连接两个节点

    • 关系是方向性的

    • 节点可以有多个甚至递归的关系

    • 关系可以有一个或多个属性(即存储为键/值对的属性)

      基于方向性,Neo4j关系被分为两种主要类型:

    • 单向关系

    • 双向关系

  • 标签

    标签(Label)将一个公共名称与一组节点或关系相关联,节点或关系可以包含一个或多个标签。我们可以为现有节点或关系创建新标签,我们可以从现有节点或关系中删除标签。

    • 标签用于节点分组
    • 一个节点可以具有多个标签
    • 对标签进行索引以加速在图中查找节点
    • 本机标签索引针对速度进行了优化
  • 数据浏览器

    一旦我们安装了Neo4j,我们就可以访问Neo4j数据浏览器

1.5、使用场景

  • 欺诈检测
  • 实时推荐引擎
  • 知识图谱

2、环境搭建

2.1、安装Neo4jCommunityServer

Windows (zip) Install

neo4j2-2

  1. If it is not already installed, get OpenJDK 8 or Oracle Java 8, recommended for Neo4j 3.0.x Version 7 is recommended for releases prior to 2.3.0.

  2. Find the zip file you just downloaded and right-click, extract all.

  3. Place the extracted files in a permanent home on your server, for example D:\neo4j\. The top level directory is referred to as NEO4J_HOME.

    • To run Neo4j as a console application, use:
      <NEO4J_HOME>\bin\neo4j console
    • To install Neo4j as a service use:
      <NEO4J_HOME>\bin\neo4j install-service.
    • For additional commands and to learn about the Windows PowerShell module included in the Zip file, see the Windows installation documentation.
  4. Visit http://localhost:7474 in your web browser.

  5. Connect using the username ‘neo4j’ with default password ‘neo4j’. You’ll then be prompted to change the password.

Neo4j Operations Manual: Windows installation →

docker install

  • 7474 for HTTP
  • 7473 for HTTPS
  • 7687 for Bolt.

拉取镜像

docker pull neo4j:3.5.22-community

运行镜像

docker run -d -p 7474:7474 -p 7687:7687 --name neo4j \
	-e "NEO4J_AUTH=neo4j/123456" \
	-v /usr/local/soft/neo4j/data:/data \
	-v /usr/local/soft/neo4j/logs:/logs \
	-v /usr/local/soft/neo4j/conf:/var/lib/neo4j/conf \
	-v /usr/local/soft/neo4j/import:/var/lib/neo4j/import \
neo4j:3.5.22-community

Start Up the Neo4j Browser

Visit: http://localhost:7474/

Open Neo4j Browser

Neo4j Browser - main panel

Once you create a new password for the ‘neo4j’ user upon visiting the Neo4j Browser the first time, you’ll have full access to the Neo4j database.

The Neo4j Browser is a tool for developers to explore their Neo4j database, execute Cypher queries and see results in tabular or graph form. You can even use the Browser to:

desktop install

Neo4jdesktop官方下载地址

填写相关信息,一键安装

3、Neo4j-CQL使用

3.1、Neo4j-CQL简介

Neo4j的Cypher语言是为处理图形数据而构建的,CQL代表Cypher查询语言。像Oracle数据库具有查询语言SQL,Neo4j具有CQL作为查询语言

  • 它是Neo4j图形数据库的查询语言
  • 它是一种声明性模式匹配语言
  • 它遵循SQL语法
  • 它的语法是非常简单且人性化、可读的格式
CQL命令用法
CREATE 创建创建节点,关系和属性
MATCH 匹配检索有关节点,关系和属性数据
RETURN 返回返回查询结果
WHERE 哪里提供条件过滤检索数据
DELETE 删除删除节点和关系
REMOVE 移除删除节点和关系的属性
ORDER BY以…排序排序检索数据
SET 组添加或更新标签

使用cypher语言来描述关系:

(fox)<-[:knows]-(周瑜)-[:knows]->(诸葛)-[:knows]->(fox)

3.2、Cypher 简介

Cypher 是一种声明式图形查询语言,允许对图形进行富有表现力和高效的查询和更新。它旨在同时适合开发人员和运营专业人员。Cypher 的设计简单而强大;可以轻松表达高度复杂的数据库查询,使您能够专注于自己的领域,而不会迷失在数据库访问中。

Cypher 受到许多不同方法的启发,并建立在表达查询的既定实践之上。许多关键字,例如WHEREand ORDER BY,都受到SQL 的启发。模式匹配借用了SPARQL 的表达式方法。一些列表语义是从 Haskell 和 Python 等语言中借用的。Cypher 的结构基于英语散文和简洁的图像,使查询既易于编写又易于阅读。

快速入门

让我们使用以下查询创建一个简单的示例图:

CREATE (john:Person {name: 'John'})
CREATE (joe:Person {name: 'Joe'})
CREATE (steve:Person {name: 'Steve'})
CREATE (sara:Person {name: 'Sara'})
CREATE (maria:Person {name: 'Maria'})
CREATE (john)-[:FRIEND]-&gt;(joe)-[:FRIEND]-&gt;(steve)
CREATE (john)-[:FRIEND]-&gt;(sara)-[:FRIEND]-&gt;(maria)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JzWg9nwu-1646578129157)(https://kroki.io/graphviz/svg/eNqtj8EKgkAQhu89xWAHT0G60iXsVEFREnV0PWztlMK2K6sFYb57q0WUBHbwNMzsfjPfz5OTZmkMKyhAKo4QZjFL0dd4UJpDlt-EadRFcuTRuAcQDCE0BUCwPQrwwSo2qDMl75Kd0fTUXqpYUpuK0jIfoyczmEDgvMiDEkpXZN9F4pGRVU-PSua_X96X5tvFLJhS2dhLOt_r_JERvyM6tYrbuYrbqrLL8dqQIe0Q06zJVAG8zgN4rS5rppNPmfIBKKKtCA==)]

例如,这里有一个查询,它在返回**“John”和找到的任何朋友的朋友之前查找名为“John”“John’s”的**朋友(尽管不是他的直接朋友)的用户。

MATCH (john {name: 'John'})-[:FRIEND]->()-[:FRIEND]->(fof)
RETURN john.name, fof.name
+----------------------+
| john.name | fof.name |
+----------------------+
| "John"    | "Steve"  |
| "John"    | "Maria"  |
+----------------------+
2 rows

接下来,我们将添加过滤以设置更多运动部件:

我们获取用户名列表并从该列表中找到所有具有名称的节点,匹配他们的朋友并仅返回那些具有以**‘S’开头的’name’**属性的关注用户。

MATCH (user)-[:FRIEND]-&gt;(follower)
WHERE user.name IN ['Joe', 'John', 'Sara', 'Maria', 'Steve'] AND follower.name =~ 'S.*'
RETURN user.name, follower.name
+---------------------------+
| user.name | follower.name |
+---------------------------+
| "Joe"     | "Steve"       |
| "John"    | "Sara"        |
+---------------------------+
2 rows

以下是用于更新图形的子句示例:

  • CREATE(和DELETE):创建(和删除)节点和关系。
  • SET(和REMOVE):设置属性值并使用SET和使用REMOVE删除它们在节点上添加标签。
  • MERGE:匹配现有的或创建新的节点和模式。这与唯一约束一起特别有用。

Neo4j官方开发文档

CREATE创建

create语句是创建模型语句用来创建数据模型

创建节点
//创建简单节点
create (n)
//创建多个节点
create (n),(m)

//创建带标签和属性的节点并返回节点
create (n:person {name:'如来'}) return n 
                   
//demo
create (:student{name:"小红"}),(:student{name:"张三"}),(:student{name:"小明"})
创建关系

Neo4j图数据库遵循属性图模型来存储和管理其数据。

根据属性图模型,关系应该是定向的。否则,Neo4j将抛出一个错误消息。

基于方向性,Neo4j关系被分为两种主要类型。

  • 单向关系
  • 双向关系
//使用新节点创建关系
CREATE (n:person {name:'杨戬'})-[r:师傅]->(m:person {name:'玉鼎真人'}) RETURN type(r)
                                                                           
//使用已知节点创建带属性的关系
MATCH (n:person {name:'沙僧'}),(m:person{name:'唐僧'})
CREATE (n)-[r:`师傅`{relation:'师傅'}]->(m) RETURN r

//检索关系节点的详细信息
MATCH(n:person)-[r]-(m:person) RETURN n,m      
    
//demo
match (n:student{name:"小明"}),(m:student{name:"小红"})
create (n)-[r:同学{relation:"同学"}]->(m) return n.name,type(r),m.name
                                                         
match (n:student),(t:teacher)
create (t)-[r:老师]->(n) return t.name,type(r),n.name
                                                         
创建全路径
CREATE p=(:person{name:'蛟魔王'})-[:义兄]->(:person{name:'牛魔王'})<-[:义兄]-(:person {name:'鹏魔王'}) RETURN p

MATCH查询

Neo4jCQL match 命令用于

  • 从数据库取有关节点和属性的数据
  • 从数据库取有关节点,关系和属性的数据
MATCH (n:`西游`) RETURN n LIMIT 25
// 忽略前面n个数据
match (n:student)return n skip 10

RETURN返回

Neo4jCQL return子句用于

  • 检索节点的某些属性
  • 检索节点的所有属性
  • 检索节点和关联关系的某些属性
  • 检索节点和关联关系的所有属性
MATCH (n:`西游`) RETURN id(n),n.name,n.tail,n.relation

WHERE子句

像SQL一样,Neo4j CQL在CQL MATCH命令中提供了WHERE子句来过滤MATCH查询的结果

MATCH (n:person) WHERE n.name='孙悟空' or n.name='猪八戒' RETURN n
//创建关系
match (n:person),(m:person) where n.name='孙悟空' and m.name='猪八戒'
create (n)-[r:师弟]->(m) return n.name,type(r),m.name

DELETE删除

Neo4j使用CQL delete子句

  • 删除节点
  • 删除节点及相关节点和关系
//删除节点(前提:节点不存在关系)
match (n:person{name:"白龙马"}) delete n
                 
//删除关系
match(n:person{name:"沙僧"})<-[r]-(m) delete r return type(r)
                                                         
//demo
match (n:student{name:"小a"})<-[r]-(m) delete r return type(r)  
match (n:student{name:"小艾"})delete n                                                           
//删除所有数据
MATCH (n) OPTIONAL MATCH (n)-[r]-() DELETE n,r
//删除所有关系和节点
MATCH (n)
DETACH DELETE n

REMOVE删除

create (n:student{name:"小c",age:20,class:"三年二班"})
//删除属性操作                   
match (n:student{name:"小c"}) remove n.age return n

SET子句

// 设置修改属性值操作,不存在的则新增,存在的则修改
match (n:student{name:"小c"})set n.age=20 return n 

ORDER BY排序

Neo4jCQL在MATCH命令中提供了"ORDER BY"子句,对MATCH查询返回的结果进行修改。

我们可以按升序或降序对行进行排序。默认情况下,它按升序对行进行排序。如果我们要按降序对它们进行排序,我们需要使用DESC子句。

//默认升序
match (n:student) return id(n),n.name order by id(n)
//降序
match (n:student) return id(n),n.name order by id(n) desc                            

UNION子句

与SQL一样,Neo4jCQL有两个子句,将两个不同的结果合并成一组结果

  • UNION

    它将两组结果中的公共行组合并返回到一组结果中。它不从两个节点返回重复的行。

    限制:

    结果列类型和来自两组结果的名称必须匹配,这意味着列名称应该相同,列的数据类型应该相同。

  • UNION ALL

    它结合并返回两个结果集的所有行成一个单一的结果集。它还会由两个节点重复行。

    限制:

    结果列类型,并从两个结果集的名字必须匹配,这意味着列名称应该是相同的,列的数据类型应该是相同的。

MATCH (n:role) RETURN n.name as name UNION 
MATCH (m:person) RETURN m.name as name

MATCH (n:role) RETURN n.name as name UNION ALL
MATCH (m:person) RETURN m.name as name

LIMIT和SKIP子句

Neo4jCQL已提供LIMIT子句和SKIP来过滤或限制查询返回的行数。

LIMIT返回前几行,SKIP忽略前几行

//前几行
MATCH (N:`西游`)RETURN n LIMIT 2
       
//忽略前两行
MATCH(n:person) RETURN n SKIP 2

NULL值

Neo4jCQL将空值视为对节点或关系的属性的缺失值或未定义值。

当我们创建一个具有现有节点标签名称但未指定其属性值的节点时,它将创建一个具有NULL属性值的新节点。

MATCH (n:`西游`) where n.label IS NULL RETURN id(n),n.name,n.tail,n.label
                                               
//demo
match (n:student{name:"小a"})set n.sex=null return n                                             
match (n:student)where n.sex is null return n

IN操作符

与SQL一样,Neo4jCQL提供了一个IN运算符,以便为CQL命令提供值的集合。

match (n:student)where n.name in["小红","小明"] return n

INDEX索引

Neo4jSQL支持节点或关系属性上的索引,以提高应用程序的性能。

我们可以为具有相同标签名称的所有节点的属性创建索引。

我们可以在MATCH或WHERE或IN运算符上使用这些索引列来改进CQLCommand的执行。

Neo4j索引操作
  • Create Index创建索引
  • Drop Index 丢弃索引
// 创建索引
create index on :`西游` (name)
// 删除索引
drop index on :`西游` (name)
                     
//demo
create index on :student (name)
drop index on :student (name)

UNIQUE约束

在Neo4j数据库中,CQL CREATE命令始终创建新的节点或关系,这意味着即使您使用相同的值,它也会插入一个新行。根据我们对某些节点或关系的应用需求,我们必须避免这种重复。

像SQL一样,Neo4j数据库也支持对NODE或Relationship的属性的UNIQUE约束

UNIQUE约束的优点
  • 避免重复记录
  • 强制执行数据完整性规则
//创建唯一约束-————-所有标签为xiyou的name属性必须是唯一的
create constraint on (n:xiyou) assert n.name is unique

//删除唯一约束
drop constraint on (n:xiyou) assert n.name is unique

DISTINCT

这个函数的用法就像SQL中的distinct关键字,返回的是所有不同值。

match (n:`西游`) return distinct(n.name)

常用函数

  • 字符串函数
  • AGGREGATION聚合
  • 关系函数
字符串函数

与SQL一样,Neo4J CQL提供了一组String函数,用于在CQL查询中获取所需的结果。
这里我们将讨论一些重要的和经常使用的功能。

功能描述
UPPER它用于将所有字母更改为大写字母。
LOWER它用于将所有字母改为小写字母。
SUBSTRING它用于获取给定String的子字符串。
REPLACE它用于替换一个字符串的子字符串。
UPPER

它需要一个字符串作为输入并转换为大写字母。 所有CQL函数应使用“()”括号。

函数语法
UPPER (<input-string>)
MATCH (e:Employee) 
RETURN e.id,UPPER(e.name),e.sal,e.deptno
LOWER

它需要一个字符串作为输入并转换为小写字母。 所有CQL函数应使用“()”括号。

函数语法
LOWER (<input-string>)
MATCH (e:Employee) 
RETURN e.id,LOWER(e.name),e.sal,e.deptno
SUBSTRING

它接受一个字符串作为输入和两个索引:一个是索引的开始,另一个是索引的结束,并返回从StartInded到EndIndex-1的子字符串。 所有CQL函数应使用“()”括号。

函数语法
SUBSTRING(<input-string>,<startIndex> ,<endIndex>)

注意:-

在Neo4J CQL中,如果一个字符串包含n个字母,则它的长度为n,索引从0开始,到n-1结束。

是SUBSTRING函数的索引值。

是可选的。 如果我们省略它,那么它返回给定字符串的子串从startIndex到字符串的结尾。

MATCH (e:Employee) 
RETURN e.id,SUBSTRING(e.name,0,2),e.sal,e.deptno

//demo 
match (n:student)where n.name="小明"return substring(n.name,1,1)                      
AGGREGATION聚合

和SQL一样,Neo4j CQL提供了一些在RETURN子句中使用的聚合函数。 它类似于SQL中的GROUP BY子句。我们可以使用MATCH命令中的RETURN +聚合函数来处理一组节点并返回一些聚合值。

聚集功能描述
COUNT它返回由MATCH命令返回的行数。
MAX它从MATCH命令返回的一组行返回最大值。
MIN它返回由MATCH命令返回的一组行的最小值。
SUM它返回由MATCH命令返回的所有行的求和值。
AVG它返回由MATCH命令返回的所有行的平均值。
COUNT

它从MATCH子句获取结果,并计算结果中出现的行数,并返回该计数值。 所有CQL函数应使用“()”括号。

函数语法
COUNT(<value>)
// 此示例演示如何使用COUNT(*)函数返回数据库中可用的Employee节点数。
MATCH (e:Employee) RETURN COUNT(*)

// demo
match (n:student)return count(n)
MAX

它采用一组行和节点或关系的作为输入,并从给定行的give 列中查找最大值。

函数语法
MAX(<property-name> )
MIN

它采用一组行和节点或关系的作为输入,并从给定行的give 列中查找最小值。

函数语法
MIN(<property-name> )

注意 -

应该是节点或关系的名称。让我们用一个例子看看MAX和MIN的功能。

MATCH (e:Employee) 
RETURN MAX(e.sal),MIN(e.sal)

AVG

它采用一组行和节点或关系的作为输入,并从给定行的give 列中查找平均值。

函数的语法
AVG(<property-name> )
SUM

它采用一组行和节点或关系的作为输入,并从给定行的give 列中查找求和值。

函数的语法
SUM(<property-name> )
MATCH (e:Employee) 
RETURN SUM(e.sal),AVG(e.sal)
关系函数

Neo4j CQL提供了一组关系函数,以在获取开始节点,结束节点等细节时知道关系的细节。在这里,我们将讨论一些重要的和经常使用的功能。

功能描述
STARTNODE它用于知道关系的开始节点。
ENDNODE它用于知道关系的结束节点。
ID它用于知道关系的ID。
TYPE它用于知道字符串表示中的一个关系的TYPE。
STARTNODE和ENDNODE

它需要一个字符串作为输入并为大写格式, 所有CQL函数应使用“()”括号。

函数语法
STARTNODE (<relationship-label-name>)
ENDNODE (<relationship-label-name>)

此示例演示如何使用CQL STARTNODE关系函数来检索关系的开始节点详细信息。
在关系“ACTION_MOVIES”上执行STARTNODE()函数之前,我们将检查其详细信息

MATCH (a)-[movie:ACTION_MOVIES]->(b) 
RETURN STARTNODE(movie)
MATCH (a)-[movie:ACTION_MOVIES]->(b) 
RETURN ENDNODE(movie)
ID和TYPE
ID和TYPE关系函数来检索关系的Id和类型详细信息。
MATCH (a)-[movie:ACTION_MOVIES]->(b) 
RETURN ID(movie),TYPE(movie)

demo1 ID和TYPE关系函数来检索关系的Id和类型详细信息。

MATCH (video1:YoutubeVideo1)-[movie:ACTION_MOVIES]->(video2:YoutubeVideo2) 
RETURN movie
MATCH (a)-[movie:ACTION_MOVIES]->(b) 
RETURN STARTNODE(movie)

demo2 使用CQL ENDNODE关系函数来检索关系的结束节点详细信息。

MATCH (video1:YoutubeVideo1)-[movie:ACTION_MOVIES]->(video2:YoutubeVideo2) 
RETURN movie
MATCH (a)-[movie:ACTION_MOVIES]->(b) 
RETURN ENDNODE(movie)

demo3 使用CQL ID和TYPE关系函数来检索关系的Id和类型详细信息。

MATCH (video1:YoutubeVideo1)-[movie:ACTION_MOVIES]->(video2:YoutubeVideo2) 
RETURN movie
MATCH (a)-[movie:ACTION_MOVIES]->(b) 
RETURN ID(movie),TYPE(movie)

)-[movie:ACTION_MOVIES]->(b)
RETURN ID(movie),TYPE(movie)


> demo1 ID和TYPE关系函数来检索关系的Id和类型详细信息。
```cypher
MATCH (video1:YoutubeVideo1)-[movie:ACTION_MOVIES]->(video2:YoutubeVideo2) 
RETURN movie
MATCH (a)-[movie:ACTION_MOVIES]->(b) 
RETURN STARTNODE(movie)

demo2 使用CQL ENDNODE关系函数来检索关系的结束节点详细信息。

MATCH (video1:YoutubeVideo1)-[movie:ACTION_MOVIES]->(video2:YoutubeVideo2) 
RETURN movie
MATCH (a)-[movie:ACTION_MOVIES]->(b) 
RETURN ENDNODE(movie)

demo3 使用CQL ID和TYPE关系函数来检索关系的Id和类型详细信息。

MATCH (video1:YoutubeVideo1)-[movie:ACTION_MOVIES]->(video2:YoutubeVideo2) 
RETURN movie
MATCH (a)-[movie:ACTION_MOVIES]->(b) 
RETURN ID(movie),TYPE(movie)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Joker.our

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值