Gstore官网学习五:支持SPARQL查询语法

一、图模式(Graph Patterns)

本文档主要参考了 SPARQL 1.1 标准文档,同时也增加了 gStore 自身定制化的内容,如果想要详细了解 gStore 支持的 SPARQL 语句,请仔细阅读我们的文档吧!

<刘亦菲> <姓名> "刘亦菲" .
<刘亦菲> <姓名> "Crystal Liu" .
<刘亦菲> <性别> "女" .
<刘亦菲> <星座> "处女座" .
<刘亦菲> <职业> "演员" .

<林志颖> <姓名> "林志颖" .
<林志颖> <性别> "男" .
<林志颖> <职业> "演员" .
<林志颖> <职业> "导演" .

<胡军> <姓名> "胡军" .
<胡军> <性别> "男" .
<胡军> <星座> "双鱼座" .
<胡军> <职业> "演员" .
<胡军> <职业> "配音" .
<胡军> <职业> "制片" .
<胡军> <职业> "导演" .

<天龙八部> <主演> <林志颖> .
<天龙八部> <主演> <刘亦菲> .
<天龙八部> <主演> <胡军> .
<天龙八部> <类型> <武侠片> .
<天龙八部> <类型> <古装片> .
<天龙八部> <类型> <爱情片> .
<天龙八部> <豆瓣评分> "8.3"^^<http://www.w3.org/2001/XMLSchema#float> .
<天龙八部> <上映时间> "2003-12-11T00:00:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> .

<恋爱大赢家> <主演> <林志颖> .
<恋爱大赢家> <主演> <刘亦菲> .
<恋爱大赢家> <类型> <爱情片> .
<恋爱大赢家> <类型> <剧情片> .
<恋爱大赢家> <豆瓣评分> "6.1"^^<http://www.w3.org/2001/XMLSchema#float> .
<恋爱大赢家> <上映时间> "2004-11-30T00:00:00"^^<http://www.w3.org/2001/XMLSchema#dateTime> .

关键词均不区分大小写。
在这里插入图片描述

1.1 最简单的图模式

我们先给出一个最简单的查询:

SELECT ?movie
WHERE
{
	?movie <主演> <刘亦菲> .
}

查询由两部分组成:

  • SELECT 语句指定需要输出查询结果的变量
  • WHERE 语句提供用来与数据图匹配的图模式

上面的查询中,图模式由单条三元组 ?movie <主演> <刘亦菲> 构成,其中作为主语的 ?movie 是变量,作为谓词的 <主演> 和作为宾语的 <刘亦菲> 是 IRI (International Resource Identifier, 国际资源标识符)。这个查询将返回由刘亦菲主演的所有影视作品,在示例数据上运行结果如下:
在这里插入图片描述

在这里插入图片描述
三元组的主语、谓词、宾语都可以是 IRI ;宾语还可以是 RDF 字面量(RDF Literal)。以下查询将给出示例数据中所有职业为导演的人物:

SELECT ?person
WHERE
{
	?person <职业> "导演" .
}

其中 “导演” 是一个 RDF 字面量。
结果如下:
在这里插入图片描述

在这里插入图片描述
当前 gStore 版本下,带有数据类型的 RDF 字面量在查询中需要添加与数据文件中相应的后缀。例如,以下查询将给出豆瓣评分为 8.3 的影视作品:

SELECT ?movie
WHERE
{
	?movie <豆瓣评分> "8.3"^^<http://www.w3.org/2001/XMLSchema#float> .
}

结果如下:
在这里插入图片描述
其他的常见数据类型包括

数据文件中也可能出现其他数据类型,只需在查询中使用 ^^<数据类型后缀> 的形式即可。

1.2 基本图模式 (Basic Graph Pattern)

基本图模式即为三元组的集合;上一节中的两个查询的 WHERE 语句均只有最外层大括号,因此属于基本图模式;加上最外层大括号,即为由单个基本图模式构成的组图模式(Group Graph Pattern)。

举例:上一节的两个查询中基本图模式都由单个三元组构成。以下查询使用了由多个三元组构成的基本图模式,将给出示例数据中天龙八部的所有男性主演:

SELECT ?person
WHERE
{
	<天龙八部> <主演> ?person .
	?person <性别> "男" .
}

结果如下:
在这里插入图片描述

1.3 组图模式 (Group Graph Pattern)

组图模式以配对的大括号分隔。组图模式既可以像上一节介绍的那样由单个基本图模式构成,也可以由多个子组图模式和以下的

  • OPTIONAL
  • UNION
  • MINUS
    三种运算嵌套而成。FILTER 则在一个组图模式的范围内过滤结果。

1.3.1 OPTIONAL

用法:pattern1 OPTIONAL { pattern2 }
pattern1 OPTIONAL { pattern2 }

查询结果必须匹配 pattern1 ,并选择性地匹配 pattern2 。pattern2 被称为 OPTIONAL 图模式。

如果 pattern2 存在匹配,则将其加入 pattern1 的匹配结果;

否则,仍然输出 pattern1 的匹配结果。

因此,OPTIONAL 常用于应对部分数据缺失的情况。

举例

下面的查询给出示例数据中人物的性别和星座信息。
其中,只要存在性别信息的人物都会被返回,不论是否同时存在该人物的星座信息;若同时存在,则额外返回。

SELECT ?person ?gender ?horoscope
WHERE
{
	?person <性别> ?gender .
	OPTIONAL
	{
		?person <星座> ?horoscope .
	}
}

结果如下:
在这里插入图片描述

1.3.2 UNION

关键词 UNION 的使用语法与 OPTIONAL 类似。

以 UNION 相连的图模式中,只要存在一个与某数据匹配,该数据就与以 UNION 相连的整体匹配。因此,UNION 可以理解为对它所连接的各图模式的匹配结果集合求并集由于允许重复结果,实际上采用多重集语义)。

举例

下面的查询给出示例数据中类别是古装片或剧情片的影视作品:

SELECT ?movie
WHERE
{
	{?movie <类型> <古装片> .}
	UNION
	{?movie <类型> <剧情片> .}
}

结果如下:
在这里插入图片描述

1.3.3 MINUS

关键词 MINUS 的使用语法与 OPTIONAL, UNION 类似。

MINUS 左边和右边的图模式的匹配均会被计算,从左边的图模式的匹配结果中移除能与右边的图模式匹配的部分作为最终结果。因此,MINUS 可以理解为对它所连接的两个图模式的匹配结果集合求差(左为被减集合,多重集语义)。

下面的查询将给出示例数据中主演了天龙八部但没有主演恋爱大赢家的人物:

举例

下面的查询将给出示例数据中主演了天龙八部但没有主演恋爱大赢家的人物:

SELECT ?person
WHERE
{
	<天龙八部> <主演> ?person .
	MINUS
	{<恋爱大赢家> <主演> ?person .}
}

结果如下:
在这里插入图片描述

1.3.4 FILTER

关键词 FILTER 之后紧随着一个约束条件,当前组图模式中不满足此条件的结果将被过滤掉,不被返回。FILTER 条件中可以使用等式、不等式以及各种内建函数

举例

下面的查询将给出示例数据中豆瓣评分高于 8 分的影视作品:

SELECT ?movie
WHERE
{
	?movie <豆瓣评分> ?score .
	FILTER (?score > "8"^^<http://www.w3.org/2001/XMLSchema#float>)
}

结果如下:
在这里插入图片描述
无论 FILTER 放置在一个组图模式中的什么位置,只要仍然处于同一个嵌套层,则其语义不变,约束条件的作用范围仍然是当前组图模式。比如以下的查询就与前一个查询等价:

SELECT ?movie
WHERE
{
	FILTER (?score > "8"^^<http://www.w3.org/2001/XMLSchema#float>)
	?movie <豆瓣评分> ?score .
}
举例2(重要)

常用于 FILTER 条件的一个内建函数是正则表达式 REGEX 。下面的查询将给出示例数据中的刘姓人物:

SELECT ?person
WHERE
{
	?person <姓名> ?name .
	FILTER REGEX(?name, "刘.*")
}

结果如下:
在这里插入图片描述

二、聚合函数 (Aggregates)

2.1 用法

聚合函数用在 SELECT 语句中,语法如下:

SELECT (AGGREGATE_NAME(?x) AS ?y)
WHERE
{
	...
}
  • AGGREGATE_NAME 是聚合函数的名称

  • 变量 ?x 是聚合函数作用的对象

  • 变量 ?y最终结果中聚合函数值的列名

聚合函数作用于各组结果。返回的全部结果默认作为一组

2.2 gStore支持的聚合函数

2.2.1 COUNT

用于计数的聚合函数。

举例

下面的查询将给出示例数据中职业为演员的人物的数目:

SELECT (COUNT(?person) AS ?count_person)
WHERE
{
	?person <职业> "演员" .
}

结果如下:
在这里插入图片描述

2.2.2 SUM

用于求和的聚合函数。

举例

下面的查询将给出示例数据中所有电影的豆瓣评分之和:

SELECT (SUM(?score) AS ?sum_score)
WHERE
{
	?movie <豆瓣评分> ?score .
}

结果如下:
在这里插入图片描述

2.2.3 AVG

用于求平均值的聚合函数。

举例

下面的查询将给出示例数据中所有电影的平均豆瓣评分:

SELECT (AVG(?score) AS ?avg_score)
WHERE
{
	?movie <豆瓣评分> ?score .
}

结果如下:
在这里插入图片描述

2.2.4 MIN

用于求最小值的聚合函数。

举例

下面的查询将给出示例数据中所有电影的最低豆瓣评分:

SELECT (MIN(?score) AS ?min_score)
WHERE
{
	?movie <豆瓣评分> ?score .
}

结果如下:
在这里插入图片描述

2.2.5 MAX

用于求最大值的聚合函数。

举例

下面的查询将给出示例数据中所有电影的最高豆瓣评分:

SELECT (MAX(?score) AS ?max_score)
WHERE
{
	?movie <豆瓣评分> ?score .
}

结果如下:
在这里插入图片描述

2.2.6 GROUP BY

如果希望按照某一个变量的值对结果分组,可以使用关键词 GROUP BY 。

举例

例如,下面的查询将给出示例数据中的所有职业及对应的人数:

SELECT ?occupation (COUNT(?person) AS ?count_person)
WHERE
{
	?person <职业> ?occupation .
}
GROUP BY ?occupation

结果如下:
在这里插入图片描述

三、结果序列修饰符(Solution Sequences and Modifiers)

3.1 定义

以下的关键词均属于结果序列修饰符,它们对查询结果做后处理,以形成最终返回的结果。

3.2 DISTINCT: 去除重复结果

SELECT 语句不带关键词 DISTINCT 的查询会在最终结果中保留重复的结果。

举例

例如下面的查询给出示例数据中所有的职业:

SELECT ?occupation
WHERE
{
	?person <职业> ?occupation .
}

结果如下:
在这里插入图片描述
如果希望查看不重复的职业种类,则可以在 SELECT 语句中添加关键词 DISTINCT :

SELECT DISTINCT ?occupation
WHERE
{
	?person <职业> ?occupation .
}

结果如下:
在这里插入图片描述
DISTINCT 也可以在聚合函数 COUNT 中使用。下面的查询给出示例数据中的职业种类数目:

SELECT (COUNT(DISTINCT ?occupation) AS ?count_occupation)
WHERE
{
	?person <职业> ?occupation .
}

结果如下:.
在这里插入图片描述

3.3 ORDER BY: 排序

查询结果默认是无序的。如果希望根据某些变量的值对结果进行排序,可以在 WHERE 语句后面添加 ORDER BY 语句。

举例

例如下面的查询将示例数据中的影视作品按照豆瓣评分排序,未指定顺序时默认为升序:

SELECT ?movie ?score
WHERE
{
	?movie <豆瓣评分> ?score
}
ORDER BY ?score

结果如下:
在这里插入图片描述

如果希望降序排序,需要用关键词 DESC 修饰变量名:

SELECT ?movie ?score
WHERE
{
	?movie <豆瓣评分> ?score
}
ORDER BY DESC(?score)

结果如下:
在这里插入图片描述
ORDER BY 语句可以包含多个以空格分隔的变量,每个变量都可用 DESC 修饰。gStore 暂不支持在 ORDER BY 语句中使用含四则运算的表达式及内建函数。

3.4 OFFSET: 跳过一定数量的结果

OFFSET 语句放在 WHERE 语句之后,
其语法如下:

OFFSET nonnegative_integer

其中 nonnegative_integer 须为非负整数,表示需要跳过的结果数量。

OFFSET 0 符合语法,但不会对结果产生影响。

由于查询结果默认无序,SPARQL 语义不保证跳过的结果满足任何确定性的条件。

因此,OFFSET 语句一般与 ORDER BY 语句配合使用。

举例

下面的查询将示例数据中的影视作品按豆瓣评分从低到高排序,并跳过评分最低的影视作品:

SELECT ?movie ?score
WHERE
{
	?movie <豆瓣评分> ?score .
}
ORDER BY ?score
OFFSET 1

结果如下:

3.5 LIMIT: 限制结果数量

LIMIT 语句的语法与 OFFSET 语句类似:

LIMIT nonnegative_integer
其中 nonnegative_integer 须为非负整数,表示允许的最大结果数量。

与 OFFSET 类似,由于查询结果默认无序,LIMIT 语句一般与 ORDER BY 语句配合使用。

举例

下面的查询给出示例数据中豆瓣评分最高的影视作品:

SELECT ?movie ?score
WHERE
{
	?movie <豆瓣评分> ?score .
}
ORDER BY DESC(?score)
LIMIT 1

结果如下:
在这里插入图片描述

四、图更新

4.1 定义

通过

  • INSERT DATA
  • DELETE DATA
  • DELETE WHERE 查询

我们可以向数据库中插入或从数据库中删除三元组。

4.2 INSERT DATA

INSERT DATA 用于向数据库中插入三元组。其语法与 SELECT 查询类似,区别在于构成组图模式的三元组中不能含有变量。

举例

下面的查询向示例数据中插入影视作品仙剑奇侠传的相关信息:

INSERT DATA
{
	<仙剑奇侠传> <主演> <胡歌> .
	<仙剑奇侠传> <主演> <刘亦菲> .
	<仙剑奇侠传> <类型> <武侠片> .
	<仙剑奇侠传> <类型> <古装片> .
	<仙剑奇侠传> <类型> <爱情片> .
	<仙剑奇侠传> <豆瓣评分> "8.9"^^<http://www.w3.org/2001/XMLSchema#float> .
}

“图模式-最简单的图模式”一节中出现过的查询

SELECT ?movie
WHERE
{
	?movie <主演> <刘亦菲> .
}

在插入上述数据后,结果变为:
在这里插入图片描述

4.3 DELETE DATA

DELETE DATA 用于从数据库中删除三元组。其用法与 INSERT DATA 完全类似。

4.4 DELETE WHERE

DELETE DATA 用于从数据库中删除符合条件的三元组;

相比起 DELETE DATA ,它的 WHERE 语句与 SELECT 查询的 WHERE 语句是完全相同的,也就是说三元组中允许含有变量。

举例

例如,下面的查询删除示例数据中所有武侠片的相关信息:

DELETE WHERE
{
	?movie <类型> <武侠片> .
	?movie ?y ?z .
}

此时再次运行“图模式-最简单的图模式”一节中出现过的查询:

SELECT ?movie
WHERE
{
	?movie <主演> <刘亦菲> .
}

结果变为:
在这里插入图片描述

五、高级功能

5.1 路径相关查询

在内核版本 v0.9 中,gStore 加入了与数据图中结点间的路径相关的一系列查询,目前包括环路查询和最短路径查询。

为了更好地演示路径相关查询的功能,使用以下的社交关系数据作为示例数据:

<Alice> <关注> <Bob> .
<Alice> <喜欢> <Bob> .
<Alice> <不喜欢> <Eve> .
<Bob> <关注> <Alice> .
<Bob> <喜欢> <Eve> .
<Carol> <关注> <Bob> .
<Carol> <喜欢> <Bob> .
<Carol> <不喜欢> <Francis> .
<Dave> <关注> <Alice> .
<Dave> <关注> <Eve> .
<Dave> <不喜欢> <Francis> .
<Eve> <喜欢> <Carol> .
<Francis> <喜欢> <Carol> .
<Francis> <不喜欢> <Dave> .
<Francis> <不喜欢> <Eve> .

上述数据的图示如下:
在这里插入图片描述
如无特殊说明,返回路径的函数均以如下 JSON 格式字符串表示一条路径/一个环/一个子图:
在这里插入图片描述

5.2 环路查询

查询是否存在包含结点 u 和 v 的一个环。

cyclePath(u, v, directed, pred_set)
cycleBoolean(u, v, directed, pred_set)

用于 SELECT 语句中,与聚合函数使用语法相同。

参数

  • u, v :变量或结点 IRI

  • directed :布尔值,为真表示有向,为假表示无向(图中所有边视为双向)

  • pred_set :构成环的边上允许出现的谓词集合。若设置为空 {} ,则表示允许出现数据中的所有谓词

返回值

  • cyclePath :以 JSON 形式返回包含结点 u 和 v 的一个环(若存在)。若 u 或 v 为变量,对变量的每组有效值返回一个环。
  • cycleBoolean :若存在包含结点 u 和 v 的一个环,返回真;否则,返回假。

举例

下面的查询询问是否存在包含 Carol 、一个 Francis 不喜欢的人(示例数据中即为 Dave 或 Eve ),且构成它的边只能由“喜欢”关系标记的有向环:

select (cycleBoolean(?x, <Carol>, true, {<喜欢>}) as ?y)
where
{
	<Francis> <不喜欢> ?x .
}

结果如下:
在这里插入图片描述
如果希望输出一个满足以上条件的环,则使用下面的查询:

SELECT (cyclePath(?x, <Carol>, true, {<喜欢>}) as ?y)
WHERE
{
	<Francis> <不喜欢> ?x .
}

结果如下,可见其中一个满足条件的环由 Eve 喜欢 Carol - Carol 喜欢 Bob - Bob 喜欢 Eve 顺次构成:(为方便阅读,省略了字符串最外层的双引号和内部双引号的转义)

{
	"paths":[{
    "src":"<Eve>",
    "dst":"<Carol>",
    "edges":
    [{"fromNode":2,"toNode":3,"predIRI":"<喜欢>"},{"fromNode":3,"toNode":1,"predIRI":"<喜欢>"},{"fromNode":1,"toNode":2,"predIRI":"<喜欢>"}],
    "nodes":
    [{"nodeIndex":1,"nodeIRI":"<Bob>"},{"nodeIndex":3,"nodeIRI":"<Carol>"},{"nodeIndex":2,"nodeIRI":"<Eve>"}]
	}]
}

下图标红的部分即为这个环:
在这里插入图片描述

5.3 最短路径查询

查询从结点 u 到结点v 的最短路径。

shortestPath(u, v, directed, pred_set)
shortestPathLen(u, v, directed, pred_set)

用于 SELECT 语句中,与聚合函数使用语法相同。

参数

  • u , v :变量或结点 IRI

  • directed :布尔值,为真表示有向,为假表示无向(图中所有边视为双向)

  • pred_set :构成最短路径的边上允许出现的谓词集合。若设置为空 {} ,则表示允许出现数据中的所有谓词

返回值

  • shortestPath :以 JSON 形式返回从结点 u 到 v 的一条最短路径(若可达)。若 u 或 v 为变量,对变量的每组有效值返回一条最短路径。
  • shortestPathLen :返回从结点 u 到 v 的最短路径长度(若可达)。若 u 或 v 为变量,对变量的每组有效值返回一个最短路径长度数值。

下面的查询返回从 Francis 到一个 Bob 喜欢、关注或不喜欢,且没有被 Francis 不喜欢的人(示例数据中即为 Alice)的最短路径,边上的关系可以是喜欢或关注:

SELECT (shortestPath(<Francis>, ?x, true, {<喜欢>, <关注>}) AS ?y)
WHERE
{
	<Bob> ?pred ?x .
	MINUS { <Francis> <不喜欢> ?x . }
}

下图标红的部分即为这条最短路径

在这里插入图片描述
结果如下:(为方便阅读,省略了字符串最外层的双引号和内部双引号的转义)

{
	"paths":[{
		"src":"<Francis>",
		"dst":"<Alice>",
		"edges":
		[{"fromNode":4,"toNode":3,"predIRI":"<喜欢>"},{"fromNode":3,"toNode":1,"predIRI":"<喜欢>"},{"fromNode":1,"toNode":0,"predIRI":"<关注>"}],
		"nodes":
		[{"nodeIndex":0,"nodeIRI":"<Alice>"},{"nodeIndex":1,"nodeIRI":"<Bob>"},{"nodeIndex":3,"nodeIRI":"<Carol>"},{"nodeIndex":4,"nodeIRI":"<Francis>"}]
		}]
}

如果希望只输出最短路径长度,则使用下面的查询:

SELECT (shortestPathLen(<Francis>, ?x, true, {<喜欢>, <关注>}) AS ?y)
WHERE
{
	<Bob> ?pred ?x .
	MINUS { <Francis> <不喜欢> ?x . }
}

结果如下:(为方便阅读,省略了字符串最外层的双引号和内部双引号的转义)

{"paths":[{"src":"<Francis>","dst":"<Alice>","length":3}]}

5.4 可达性 / K 跳可达性查询

查询从结点 u 到结点 v 是否可达 / 是否 K 跳可达(即存在以 u 为起点、以 v 为终点,长度小于或等于 K 的路径)。

kHopReachable(u, v, directed, k, pred_set)
kHopReachablePath(u, v, directed, k, pred_set)

参数

  • u, v :变量或结点 IRI

  • k :若置为非负整数,则为路径长度上限(查询 K 跳可达性);若置为负数,则查询可达性

  • directed :布尔值,为真表示有向,为假表示无向(图中所有边视为双向)

  • pred_set :构成路径的边上允许出现的谓词集合。若设置为空 {} ,则表示允许出现数据中的所有谓词

返回值

  • kHopReachable:若从结点 u 到结点 v 可达(或 K 跳可达,取决于参数 k 的取值),返回真;否则,返回假。若 u 或 v 为变量,对变量的每组有效值返回一个真/假值。
  • kHopReachablePath:返回任意一条从结点 u 到结点 v 的路径(若可达)或K跳路径,即长度小于或等于k的路径(若K跳可达,取决于参数 k 的取值)。若 u 或 v 为变量,对变量的每组有效值返回一条路径(若可达)或K跳路径(若K跳可达)。

下面的查询效仿上一节“最短路径查询”中的示例查询:起点为 Francis ,终点为一个 Bob 喜欢、关注或不喜欢,且没有被 Francis 不喜欢的人(示例数据中即为 Alice)。询问这两人之间是否通过喜欢或关注关系 2 跳或以内可达。

SELECT (kHopReachable(<Francis>, ?x, true, 2, {<喜欢>, <关注>}) AS ?y)
WHERE
{
	<Bob> ?pred ?x .
	MINUS { <Francis> <不喜欢> ?x . }
}

由于已知满足条件的最短路径长度为 3 :
在这里插入图片描述
因此上述查询的结果为假:

{"paths":[{"src":"<Francis>","dst":"<Alice>","value":"false"}]}

另一方面,Francis 和 Alice 之间是可达的,只是最短路径长度超出了上述限制。因此若查询可达性(将 k 设置为负数),则会返回真:

SELECT (kHopReachable(<Francis>, ?x, true, -1, {<喜欢>, <关注>}) AS ?y)
WHERE
{
	<Bob> ?pred ?x .
	MINUS { <Francis> <不喜欢> ?x . }
}

结果如下:

{"paths":[{"src":"<Francis>","dst":"<Alice>","value":"true"}]}

若希望返回一条两人之间满足条件的路径,则可以调用kHopReachablePath函数:

SELECT (kHopReachablePath(<Francis>, ?x, true, -1, {<喜欢>, <关注>}) AS ?y)
WHERE
{
	<Bob> ?pred ?x .
	MINUS { <Francis> <不喜欢> ?x . }
}

此时结果可能为上述最短路径:

{
	"paths":[{
		"src":"<Francis>",
		"dst":"<Alice>",
		"edges":
		[{"fromNode":4,"toNode":3,"predIRI":"<喜欢>"},{"fromNode":3,"toNode":1,"predIRI":"<喜欢>"},{"fromNode":1,"toNode":0,"predIRI":"<关注>"}],
		"nodes":
		[{"nodeIndex":0,"nodeIRI":"<Alice>"},{"nodeIndex":1,"nodeIRI":"<Bob>"},{"nodeIndex":3,"nodeIRI":"<Carol>"},{"nodeIndex":4,"nodeIRI":"<Francis>"}]
		}]
}

也可能是下图中含有环的、同样满足条件的非最短路径:
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值