Skip to content

Commit

Permalink
insert if not exist (#638)
Browse files Browse the repository at this point in the history
* insert if not exist

* update

* update

* update

* Update 2.data-model.md

* update

* update

* update

* update

Co-authored-by: min.wu <50101159+whitewum@users.noreply.github.com>
  • Loading branch information
cooper-lzy and whitewum committed Jun 23, 2021
1 parent 7fd19fa commit 2862dd4
Show file tree
Hide file tree
Showing 83 changed files with 559 additions and 517 deletions.
10 changes: 5 additions & 5 deletions docs-2.0/1.introduction/2.data-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,25 +15,25 @@ Nebula Graph数据模型使用6种基本的数据结构:
点用来保存实体对象,特点如下:

- 点是用点标识符(`VID`)标识的。`VID`在同一图空间中唯一。VID 是一个 int64, 或者 fixed_string(N)。
- 点必须有至少一个标签(Tag),也可以有多个标签
- 点必须有至少一个Tag,也可以有多个Tag。但不能没有Tag

- 边(edge)

边是用来连接点的,表示两个点之间的关系或行为,特点如下:

- 两点之间可以有多条边。
- 边是有方向的,不存在无向边。
- 四元组 `<起点VID、边类型(edge type、边排序值(rank)、终点VID>` 用于唯一标识一条边。边没有EID。
- 一条边有且仅有一个边类型
- 四元组 `<起点VID、Edge type、边排序值(rank)、终点VID>` 用于唯一标识一条边。边没有EID。
- 一条边有且仅有一个Edge type
- 一条边有且仅有一个rank。其为int64, 默认为0。

- 标签(tag)

标签由一组事先预定义的属性构成
Tag由一组事先预定义的属性构成

- 边类型(edge type)

边类型由一组事先预定义的属性构成
Edge type由一组事先预定义的属性构成

- 属性(properties)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Nebula Graph支持多个图空间,不同图空间内的数据是安全隔离

### 管理Schema信息

Nebula Graph是强类型图数据库,它的Schema包括标签、边类型、标签属性和边类型属性
Nebula Graph是强类型图数据库,它的Schema包括Tag、Edge type、Tag属性和Edge type属性

Meta服务中存储了Schema信息,同时还负责Schema的添加、修改和删除,并记录它们的版本。

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ Validator模块对生成的AST进行语义校验,主要包括:

校验语句中的元数据信息是否正确。

例如解析`OVER``WHERE``YIELD`语句时,会查找Schema校验边类型、标签的信息是否存在,或者插入数据时校验插入的数据类型和Schema中的是否一致。
例如解析`OVER``WHERE``YIELD`语句时,会查找Schema校验Edge type、Tag的信息是否存在,或者插入数据时校验插入的数据类型和Schema中的是否一致。

- 校验上下文引用信息

Expand All @@ -50,7 +50,7 @@ Validator模块对生成的AST进行语义校验,主要包括:

查询语句中包含`*`时,校验子句时需要将`*`涉及的Schema都进行校验。

例如语句`GO FROM "Tim" OVER * YIELD like._dst, like.likeness, serve._dst`,校验`OVER`子句时需要校验所有的边类型,如果边类型包含`like``serve`,该语句会展开为`GO FROM "Tim" OVER like,serve YIELD like._dst, like.likeness, serve._dst`
例如语句`GO FROM "Tim" OVER * YIELD like._dst, like.likeness, serve._dst`,校验`OVER`子句时需要校验所有的Edge type,如果Edge type包含`like``serve`,该语句会展开为`GO FROM "Tim" OVER like,serve YIELD like._dst, like.likeness, serve._dst`

- 校验输入输出

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ Nebula Graph使用自行开发的KVStore,而不是其他开源KVStore,原因
|`Type`|key类型。长度为1个字节。|
|`PartID`|数据分片编号。长度为3个字节。此字段主要用于Storage负载均衡(balance)时方便根据前缀扫描整个分片的数据。|
|`VertexID`|点ID。当点ID类型为int时,长度为8个字节;当点ID类型为string时,长度为创建图空间时指定的`fixed_string`长度。|
|`TagID`|点关联的标签ID。长度为4个字节。|
|`TagID`|点关联的Tag ID。长度为4个字节。|

- 边数据存储格式

Expand All @@ -104,7 +104,7 @@ Nebula Graph使用自行开发的KVStore,而不是其他开源KVStore,原因

2.0和1.x的差异如下:

- 1.x中,点和边的`Type`值相同,而在2.0中进行了区分,即在物理上分离了点和边,方便快速查询某个点的所有标签
- 1.x中,点和边的`Type`值相同,而在2.0中进行了区分,即在物理上分离了点和边,方便快速查询某个点的所有Tag
- 1.x中,`VertexID`仅支持int类型,而在2.0中新增了string类型。
- 2.0中取消了1.x中的保留字段`Timestamp`。
- 2.0中边数据新增字段`PlaceHolder`。
Expand Down Expand Up @@ -144,7 +144,7 @@ EdgeA_Out和EdgeA_In以方向相反的两条边的形式存在于存储层,二

### 分片算法

分片策略采用**静态 Hash**的方式,即对点VID进行取模操作,同一个点的所有标签、出边和入边信息都会存储到同一个分片,这种方式极大地提升了查询效率。
分片策略采用**静态 Hash**的方式,即对点VID进行取模操作,同一个点的所有Tag、出边和入边信息都会存储到同一个分片,这种方式极大地提升了查询效率。

!!! Note

Expand Down
4 changes: 2 additions & 2 deletions docs-2.0/1.introduction/3.vid.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@

- VID相同的点,会被认为是同一个点。例如:

+ VID相当于一个实体的唯一标号,例如一个人的身份证号。标签(Tag)相当于实体所拥有的类型,例如"滴滴司机"和"老板"。不同的Tag又相应定义了两组不同的属性,例如"驾照号、驾龄、接单量、接单小号"和"工号、薪水、债务额度、商务电话"。
+ VID相当于一个实体的唯一标号,例如一个人的身份证号。Tag相当于实体所拥有的类型,例如"滴滴司机"和"老板"。不同的Tag又相应定义了两组不同的属性,例如"驾照号、驾龄、接单量、接单小号"和"工号、薪水、债务额度、商务电话"。

+ 同时操作相同VID并且相同Tag的两条`INSERT`语句,晚写入的`INSERT`会覆盖先写入的。
+ 同时操作相同VID并且相同Tag的两条`INSERT`语句(均无`IF NOT EXISTS`参数),晚写入的`INSERT`会覆盖先写入的。

+ 同时操作包含相同VID但是两个不同`TAG A``TAG B`的两条`INSERT`语句,对`TAG A`的操作不会影响`TAG B`

Expand Down
20 changes: 10 additions & 10 deletions docs-2.0/2.quick-start/4.nebula-graph-crud.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
| 点(vertex) | 表示现实世界中的实体。一个点可以有一个或多个标签。 |
| 标签(tag) | 点的类型,定义了一组描述点类型的属性。 |
| 边(edge) | 表示两个点之间**有方向**的关系。|
| 边类型(edge type) | 边的类型,定义了一组描述边类型的属性|
| 边类型(edge type) | 边的类型,定义了一组描述边的类型的属性|

更多信息,请参见[数据结构](../1.introduction/2.data-model.md)

Expand Down Expand Up @@ -154,7 +154,7 @@ Nebula Graph中执行如下创建和修改操作,是异步实现的,需要
Got 1 rows (time spent 977/2000 us)
```

## 创建标签和边类型
## 创建Tag和Edge type

### nGQL语法

Expand All @@ -165,7 +165,7 @@ CREATE {TAG | EDGE} {<tag_name> | <edge_type>}(<property_name> <data_type>

### 示例

创建标签`player``team`以及边类型`follow``serve`。说明如下表。
创建Tag`player``team`以及Edge type`follow``serve`。说明如下表。

| 名称 | 类型 | 属性 |
| :--- | :--- | :--- |
Expand Down Expand Up @@ -198,14 +198,14 @@ Wed, 24 Feb 2021 03:48:16 EST

## 插入点和边

用户可以使用`INSERT`语句,基于现有的标签插入点,或者基于现有的边类型插入边
用户可以使用`INSERT`语句,基于现有的Tag插入点,或者基于现有的Edge type插入边

### nGQL语法

- 插入点

```ngql
INSERT VERTEX <tag_name> (<property_name>[, <property_name>...])
INSERT VERTEX [IF NOT EXISTS] <tag_name> (<property_name>[, <property_name>...])
[, <tag_name> (<property_name>[, <property_name>...]), ...]
{VALUES | VALUE} <vid>: (<property_value>[, <property_value>...])
[, <vid>: (<property_value>[, <property_value>...];
Expand All @@ -216,7 +216,7 @@ Wed, 24 Feb 2021 03:48:16 EST
- 插入边

```ngql
INSERT EDGE <edge_type> (<property_name>[, <property_name>...])
INSERT EDGE [IF NOT EXISTS] <edge_type> (<property_name>[, <property_name>...])
{VALUES | VALUE} <src_vid> -> <dst_vid>[@<rank>] : (<property_value>[, <property_value>...])
[, <src_vid> -> <dst_vid>[@<rank>] : (<property_name>[, <property_name>...]), ...];
```
Expand Down Expand Up @@ -294,7 +294,7 @@ Wed, 24 Feb 2021 03:48:16 EST

- `FETCH`

- 查询标签属性
- 查询Tag属性

```ngql
FETCH PROP ON {<tag_name> | <tag_name_list> | *} <vid_list>
Expand Down Expand Up @@ -537,7 +537,7 @@ Got 1 rows (time spent 2006/2406 us)

## 索引

用户可以通过[CREATE INDEX](../3.ngql-guide/14.native-index-statements/1.create-native-index.md)语句为标签(tag)和边类型(edge type)增加索引
用户可以通过[CREATE INDEX](../3.ngql-guide/14.native-index-statements/1.create-native-index.md)语句为Tag和Edge type增加索引

### 使用索引必读

Expand All @@ -562,7 +562,7 @@ Got 1 rows (time spent 2006/2406 us)

### 示例

为标签`player`的属性`name`创建索引,并且重建索引。
为Tag`player`的属性`name`创建索引,并且重建索引。

```ngql
nebula> CREATE TAG INDEX player_index_0 on player(name(20));
Expand All @@ -577,7 +577,7 @@ nebula> REBUILD TAG INDEX player_index_0;

确保`LOOKUP``MATCH`有一个索引可用。如果没有,请先创建索引。

找到标签为`player`的点的信息,它的`name`属性值为`Tony Parker`
找到Tag为`player`的点的信息,它的`name`属性值为`Tony Parker`

```nGQL
// 为name属性创建索引player_name_0。
Expand Down
8 changes: 4 additions & 4 deletions docs-2.0/20.appendix/0.FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,11 @@ Storage服务使用Raft协议(多数表决),为保证可用性,要求出

大部分情况下,查询语句需要有`YIELD``RETURN`,请检查查询语句是否包含。

### 如何统计每种Tag有多少个点,每个边类型有多少条边?
### 如何统计每种Tag有多少个点,每个Edge type有多少条边?

请参见[show-stats](../3.ngql-guide/7.general-query-statements/6.show/14.show-stats.md)

### 如何获取每种Tag的所有点,或者每种边类型的所有边?
### 如何获取每种Tag的所有点,或者每种Edge type的所有边?

1. 建立并重建索引。

Expand Down Expand Up @@ -167,9 +167,9 @@ Storage服务在毫秒级时间内多次收到插入或者更新同一点或边

不支持。即使关闭了客户端,服务端仍会尽力把该查询执行完毕,无法中断。

### 能不能用中文字符做标识符,比如图空间、标签、边类型、属性、索引的名称?
### 能不能用中文字符做标识符,比如图空间、Tag、Edge type、属性、索引的名称?

不能。图空间、标签、边类型、属性以及索引的名称都需由大小写英文字母、数字或下划线组成,暂不支持使用中文字符。
不能。图空间、Tag、Edge type、属性以及索引的名称都需由大小写英文字母、数字或下划线组成,暂不支持使用中文字符。

同时,上述标识符区分大小写,且不可使用[关键字和保留字](../3.ngql-guide/1.nGQL-overview/keywords-and-reserved-words.md)

Expand Down
10 changes: 5 additions & 5 deletions docs-2.0/3.ngql-guide/1.nGQL-overview/3.graph-patterns.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,19 @@
(a)-[]->()<-[]-(c)
```

## 标签模式
## Tag模式

!!! Note

nGQL中的`tag`概念与openCypher中的`label`有一些不同。例如,您必须创建一个`tag`之后才能使用它,而且`tag`还定义了属性的类型。

模式除了简单地描述图中的点之外,还可以描述点的标签。例如:
模式除了简单地描述图中的点之外,还可以描述点的Tag。例如:

```ngql
(a:User)-[]->(b)
```

模式也可以描述有多个标签的点,例如:
模式也可以描述有多个Tag的点,例如:

```ngql
(a:User:Admin)-[]->(b)
Expand Down Expand Up @@ -86,13 +86,13 @@
(a)-[r]->(b)
```

和点上的标签一样,边也可以有类型。描述边的类型,例如:
和点上的Tag一样,边也可以有类型。描述边的类型,例如:

```ngql
(a)-[r:REL_TYPE]->(b)
```

和点上的标签不同,一条边只能有一种边类型。但是如果我们想描述多个可选边类型,可以用管道符号(|)将可选值分开,例如:
和点上的Tag不同,一条边只能有一种Edge type。但是如果我们想描述多个可选Edge type,可以用管道符号(|)将可选值分开,例如:

```ngql
(a)-[r:TYPE1|TYPE2]->(b)
Expand Down
32 changes: 16 additions & 16 deletions docs-2.0/3.ngql-guide/10.tag-statements/1.create-tag.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# CREATE TAG

`CREATE TAG`语句可以通过指定名称创建一个标签
`CREATE TAG`语句可以通过指定名称创建一个Tag

## OpenCypher兼容性

Expand All @@ -11,11 +11,11 @@ nGQL中的tag和openCypher中的label相似,但又有所不同,例如它们

## 前提条件

执行`CREATE TAG`语句需要当前登录的用户拥有指定图空间的[创建标签权限](../../7.data-security/1.authentication/3.role-list.md),否则会报错。
执行`CREATE TAG`语句需要当前登录的用户拥有指定图空间的[创建Tag权限](../../7.data-security/1.authentication/3.role-list.md),否则会报错。

## 语法

创建标签前,需要先用`USE`语句指定工作空间。
创建Tag前,需要先用`USE`语句指定工作空间。

```ngql
CREATE TAG [IF NOT EXISTS] <tag_name>
Expand All @@ -34,21 +34,21 @@ CREATE TAG [IF NOT EXISTS] <tag_name>
| DEFAULT <default_value>
```

### 标签名称
### Tag名称

- `IF NOT EXISTS`:用户可以使用`IF NOT EXISTS`关键字检测待创建的标签是否存在,只有不存在时,才会创建标签
- `IF NOT EXISTS`:用户可以使用`IF NOT EXISTS`关键字检测待创建的Tag是否存在,只有不存在时,才会创建Tag

!!! Note

仅检测标签的名称,不会检测具体属性。
仅检测Tag的名称,不会检测具体属性。

- `tag_name`每个图空间内的标签必须是唯一的。标签名称设置后无法修改。标签名称由大小写英文字母、数字或下划线组成,区分大写小,且不可使用[关键字和保留字](../../3.ngql-guide/1.nGQL-overview/keywords-and-reserved-words.md)
- `tag_name`每个图空间内的Tag必须是唯一的。Tag名称设置后无法修改。Tag名称由大小写英文字母、数字或下划线组成,区分大写小,且不可使用[关键字和保留字](../../3.ngql-guide/1.nGQL-overview/keywords-and-reserved-words.md)

### 标签属性
### Tag属性

- `prop_name`

属性名称。每个标签中的属性名称必须唯一。属性的命名规则与标签相同
属性名称。每个Tag中的属性名称必须唯一。属性的命名规则与Tag相同

- `data_type`

Expand All @@ -72,17 +72,17 @@ CREATE TAG [IF NOT EXISTS] <tag_name>

指定要设置存活时间的属性。属性的数据类型必须是`int`或者`timestamp`

一个标签只能指定一个字段为`TTL_COL`。更多TTL的信息请参见[TTL](../8.clauses-and-options/ttl-options.md)
一个Tag只能指定一个字段为`TTL_COL`。更多TTL的信息请参见[TTL](../8.clauses-and-options/ttl-options.md)

## 示例

```ngql
nebula> CREATE TAG player(name string, age int);
# 创建没有属性的标签
# 创建没有属性的Tag
nebula> CREATE TAG no_property(); 
# 创建包含默认值的标签
# 创建包含默认值的Tag
nebula> CREATE TAG player_with_default(name string, age int DEFAULT 20);
# 对字段create_time设置TTL为100秒。
Expand All @@ -91,13 +91,13 @@ nebula> CREATE TAG woman(name string, age int, \
TTL_DURATION = 100, TTL_COL = "create_time";
```

## 创建标签说明
## 创建Tag说明

尝试使用新创建的标签可能会失败,因为创建是异步实现的。
尝试使用新创建的Tag可能会失败,因为创建是异步实现的。

Nebula Graph将在下一个心跳周期内完成标签的创建,为了确保创建成功,可以使用如下方法之一:
Nebula Graph将在下一个心跳周期内完成Tag的创建,为了确保创建成功,可以使用如下方法之一:

-[`SHOW TAGS`](4.show-tags.md)语句的结果中查找新的标签,如果找不到,请等待几秒重试。
-[`SHOW TAGS`](4.show-tags.md)语句的结果中查找新的Tag,如果找不到,请等待几秒重试。

- 等待两个心跳周期,例如20秒。

Expand Down
20 changes: 10 additions & 10 deletions docs-2.0/3.ngql-guide/10.tag-statements/2.drop-tag.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,30 @@
# DROP TAG

`DROP TAG`语句可以删除当前工作空间内的指定标签
`DROP TAG`语句可以删除当前工作空间内的指定Tag

点可以有一个或多个标签
点可以有一个或多个Tag

- 如果某个点只有一个标签,删除这个标签后,用户就**无法访问**这个点,下次Compaction操作时会删除该点,但点上的边仍然存在。
- 如果某个点只有一个Tag,删除这个Tag后,用户就**无法访问**这个点,下次Compaction操作时会删除该点,但点上的边仍然存在。

- 如果某点有多个标签,删除其中一个标签,仍然可以访问这个点,但是**无法访问**已删除标签定义的所有属性
- 如果某点有多个Tag,删除其中一个Tag,仍然可以访问这个点,但是**无法访问**已删除Tag定义的所有属性

删除标签操作仅删除Schema数据,硬盘上的文件或目录不会立刻删除,而是在下一次Compaction操作时删除。
删除Tag操作仅删除Schema数据,硬盘上的文件或目录不会立刻删除,而是在下一次Compaction操作时删除。

## 前提条件

- 登录的用户必须拥有对应权限才能执行`DROP TAG`语句。详情请参见[内置角色权限](../../7.data-security/1.authentication/3.role-list.md)

- 确保标签不包含任何索引,否则`DROP TAG`时会报冲突错误`[ERROR (-8)]: Conflict!`。删除索引请参见[drop index](../14.native-index-statements/6.drop-native-index.md)
- 确保Tag不包含任何索引,否则`DROP TAG`时会报冲突错误`[ERROR (-8)]: Conflict!`。删除索引请参见[drop index](../14.native-index-statements/6.drop-native-index.md)

## 语法

```ngql
DROP TAG [IF EXISTS] <tag_name>;
```

- `IF NOT EXISTS`检测待删除的标签是否存在,只有存在时,才会删除标签
- `IF NOT EXISTS`检测待删除的Tag是否存在,只有存在时,才会删除Tag

- `tag_name`指定要删除的标签名称。一次只能删除一个标签
- `tag_name`指定要删除的Tag名称。一次只能删除一个Tag

## 示例

Expand All @@ -35,9 +35,9 @@ nebula> DROP TAG test;

!!! Note

nGQL中没有移除指定点的某个标签的语句
nGQL中没有移除指定点的某个Tag的语句

* 在openCypher中,可以使用`REMOVE v:LABEL`语句来移除该点`v`的标签`LABLE`。
* 在openCypher中,可以使用`REMOVE v:LABEL`语句来移除该点`v`的Tag`LABLE`。
* 在nGQL中,通过`CREATE TAG`和`INSERT VERTEX`语句后,可以为该点增加一个`TAG`;但是没有任何办法移除这个点的`TAG`。

建议在schema中增加一个字段来标识软移除,例如为每个TAG的schema增加一个字段`removed`。
Loading

0 comments on commit 2862dd4

Please sign in to comment.